【springboot】中使用--WebMvcConfigurer

MAGICIAN... 2024-09-03 13:03:05 阅读 62

WebMvcConfigurer

一、页面跳转控制器step1:创建视图,resources/templates/index.htmlstep2:创建SpringMVC配置类step3:测试功能

二、数据格式化step1:创建 DeviceInfo 数据类step2:自定义 Formatterstep3: 登记自定义的 DeviceFormatterstep4: 新建 Controller 接受请求设备数据step5:单元测试

三、拦截器(一)、一个拦截器step1:创建文章的 Controllerstep2:创建有关权限拦截器step3:登记拦截器step4:测试拦截器

(二)、多个拦截器step1:创建登录拦截器step2:登记拦截器,设置顺序 orderstep3:测试拦截器

WebMvcConfigurer 作为配置类是,采用 JavaBean 的形式来代替传统的 xml 配置文件形式进行针对框架个性化定制,就是 Spring MVC XML 配置文件的 JavaConfig(编码)实现方式。自定义 InterceptorViewResolver,

MessageConverter。WebMvcConfigurer 就是 JavaConfig 形式的 Spring MVC 的配置文件WebMvcConfigurer 是一个接口,需要自定义某个对象,实现接口并覆盖某个方法。主要方法功能介绍一下:

在这里插入图片描述

<code>public interface WebMvcConfigurer { -- -->

//帮助配置 HandlerMapping

default void configurePathMatch(PathMatchConfigurer configurer) {

}

//处理内容协商

default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

}

//异步请求

default void configureAsyncSupport(AsyncSupportConfigurer configurer) {

}

//配置默认 servlet

default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

}

//配置内容转换器

default void addFormatters(FormatterRegistry registry) {

}

//配置拦截器

default void addInterceptors(InterceptorRegistry registry) {

}

//处理静态资源

default void addResourceHandlers(ResourceHandlerRegistry registry) {

}

//配置全局跨域

default void addCorsMappings(CorsRegistry registry) {

}

//配置视图页面跳转

default void addViewControllers(ViewControllerRegistry registry) {

}

//配置视图解析器

default void configureViewResolvers(ViewResolverRegistry registry) {

}

//自定义参数解析器,处理请求参数

default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {

}

//自定义控制器方法返回值处理器

default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {

}

//配置 HttpMessageConverters

default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

}

//配置 HttpMessageConverters

default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {

}

//配置异常处理器

default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {

}

//扩展异常处理器

default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {

}

//JSR303 的自定义验证器

default Validator getValidator() {

return null;

}

//消息处理对象

default MessageCodesResolver getMessageCodesResolver() {

return null;

}

}

一、页面跳转控制器

Spring Boot 中使用页面视图,比如 Thymeleaf。要跳转显示某个面,必须通过 Controller 对象。也就是我们需要创建一个 Controller,转发到一个视图才行。 如果我们现在需要显示页面,可以无需这个 Controller。

addViewControllers() 完成从请求到视图跳转。

需求:访问/welcome 跳转到项目首页 index.html(Thyemeleaf 创建的对象)

项目代码结构:

在这里插入图片描述

step1:创建视图,resources/templates/index.html

<code><!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<title>Title</title>

</head>

<body>

<h3>欢迎各位小伙伴!!!</h3>

</body>

</html>

step2:创建SpringMVC配置类

重写addViewControllers()方法配置页面控制:addViewController(“请求的uri”).指定他的视图setViewName(目标视图)

在这里插入图片描述

<code>package com.bjpowernode.mvc.settings;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**

* springmvc配置类

*/

@Configuration

public class MvcSettings implements WebMvcConfigurer { -- -->

//页面跳转控制器,从请求直达视图

@Override

public void addViewControllers(ViewControllerRegistry registry) {

//配置页面控制:addViewController("请求的uri").指定他的视图setViewName(目标视图)

registry.addViewController("/welcome").setViewName("index");

}

}

step3:测试功能

浏览器访问http://localhost:8080/welcome

在这里插入图片描述

二、数据格式化

Formatter<T>是数据转换接口,将一种数据类型转换为另一种数据类型。与 Formatter<T>功能类型的还有Converter<S,T>。本节研究 Formatter<T>接口。Formatter<T>只能将 String 类型转为其他数据数据类型。这点在Web 应用适用更广。因为 Web 请求的所有参数都是 String,我们需要把 String 转为 Integer ,Long,Date 等等。

Spring 中内置了一下 Formatter:

DateFormatter : String 和 Date 之间的解析与格式化InetAddressFormatter :String 和 InetAddress 之间的解析与格式化PercentStyleFormatter :String 和 Number 之间的解析与格式化,带货币符合NumberFormat :String 和 Number 之间的解析与格式化

我在使用@ DateTimeFormat , @NumberFormat 注解时,就是通过 Formatter解析 String 类型到我们期望的Date 或 Number 类型Formatter也是 Spring 的扩展点,我们处理特殊格式的请求数据时,能够自定义合适的 Formatter,将请求的 String 数据转为我们的某个对象,使用这个对象更方便我们的后续编码

接口原型

在这里插入图片描述

Formatter是一个组合接口,没有自己的方法。内容来自 Printer和 Parser

Printer:将 T 类型转为 String,格式化输出Parser:将 String 类型转为期望的 T 对象。

我们项目开发,可能面对多种类型的项目,复杂程度有简单,有难一些。特别是与硬件打交道的项目,数据的格式与一般的 name: lisi, age:20 不同。数据可能是一串“1111; 2222; 333,NF; 4; 561” 。需求:将“1111;2222;333,NF;4;561”接受,代码中用 DeviceInfo 存储参数值

step1:创建 DeviceInfo 数据类

<code>import lombok.Data;

@Data

public class DeviceInfo { -- -->

private String item1;

private String item2;

private String item3;

private String item4;

private String item5;

}

step2:自定义 Formatter

package com.bjpowernode.mvc.fomatter;

import com.bjpowernode.mvc.model.DeviceInfo;

import org.springframework.format.Formatter;

import org.springframework.util.StringUtils;

import java.text.ParseException;

import java.util.Locale;

import java.util.StringJoiner;

/**

* 将请求参数字符串转为 DeviceInfo

*/

public class DeviceFormatter implements Formatter<DeviceInfo> {

@Override

public DeviceInfo parse(String text, Locale locale) throws ParseException {

DeviceInfo info = null;

if(StringUtils.hasLength(text)){

String[] items = text.split(";");

info = new DeviceInfo();

info.setItem1(items[0]);

info.setItem2(items[1]);

info.setItem3(items[2]);

info.setItem4(items[3]);

info.setItem5(items[4]);

}

return info;

}

@Override

public String print(DeviceInfo object, Locale locale) {

StringJoiner joiner = new StringJoiner("#");

joiner.add(object.getItem1()).add(object.getItem2())

.add(object.getItem3()).add(object.getItem4()).add(object.getItem5());

return joiner.toString();

}

}

step3: 登记自定义的 DeviceFormatter

addFormatters() 方法登记 Formatter

在这里插入图片描述

<code>package com.bjpowernode.mvc.settings;

import com.bjpowernode.mvc.fomatter.DeviceFormatter;

import org.springframework.context.annotation.Configuration;

import org.springframework.format.FormatterRegistry;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**

* springmvc配置类

*/

@Configuration

public class MvcSettings implements WebMvcConfigurer { -- -->

//页面跳转控制器,从请求直达视图

@Override

public void addViewControllers(ViewControllerRegistry registry) {

//配置页面控制:addViewController("请求的uri").指定他的视图setViewName(目标视图)

registry.addViewController("/welcome").setViewName("index");

}

@Override

public void addFormatters(FormatterRegistry registry) {

registry.addFormatter(new DeviceFormatter());

}

}

step4: 新建 Controller 接受请求设备数据

import com.bjpowernode.mvc.model.DeviceInfo;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class DeviceController {

@PostMapping("/device/add")

public String addDeviceInfo(@RequestParam("device")DeviceInfo info){

return "接受设备信息"+info.toString();

}

}

step5:单元测试

POST http://localhost:8080/device/add

Content-Type: application/x-www-form-urlencoded

device=1111;2222;333,NF;4;561

在这里插入图片描述

三、拦截器

HandlerInterceptor 接口和它的实现类称为拦截器,是 SpringMVC 的一种对象。拦截器是 Spring MVC 框架的对象与 Servlet 无关。拦截器能够预先处理发给 Controller 的请求。可以决定请求是否被 Controller 处理。用户请求是先由 DispatcherServlet 接收后,在 Controller 之前执行的拦截器对象。

一个项目中有众多的拦截器:框架中预定义的拦截器, 自定义拦截器。下面我说说自定义拦截器的应用。根据拦截器的特点,类似权限验证,记录日志,过滤字符,登录 token 处理都可以使用拦截器。

拦截器定义步骤:

声明类实现 HandlerInterceptor 接口,重写三个方法(需要那个重写那个)登记拦截器

(一)、一个拦截器

需求:zhangsan 操作员用户,只能查看文章,不能修改,删除。

step1:创建文章的 Controller

<code>import org.springframework.web.bind.annotation.DeleteMapping;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class ArticleController { -- -->

@PostMapping("/article/add")

public String addArticle(){

return "发布新的文章";

}

@PostMapping("/article/edit")

public String editArticle(){

return "修改文章";

}

@DeleteMapping("/article/remove")

public String removeArticle(){

return "删除文章";

}

@GetMapping("/article/query")

public String query(){

return "查询文章";

}

}

step2:创建有关权限拦截器

import jakarta.servlet.http.HttpServletRequest;

import jakarta.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

public class AuthInterceptor implements HandlerInterceptor {

private static final String COMMON_USER="zhangsan";code>

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { -- -->

System.out.println("====AuthInterceptor权限拦截器====");

String loginUser = request.getParameter("loginUser");

String requestURI = request.getRequestURI();

if(COMMON_USER.equals(loginUser) && (

requestURI.startsWith("/article/add")||

requestURI.startsWith("/article/edit")||

requestURI.startsWith("/article/remove")

)){

return false;

}

return true;

}

}

step3:登记拦截器

在这里插入图片描述

<code>package com.bjpowernode.mvc.settings;

import com.bjpowernode.mvc.fomatter.DeviceFormatter;

import com.bjpowernode.mvc.interceptor.AuthInterceptor;

import com.bjpowernode.mvc.interceptor.LoginInterceptor;

import org.springframework.context.annotation.Configuration;

import org.springframework.format.FormatterRegistry;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**

* springmvc配置类

*/

@Configuration

public class MvcSettings implements WebMvcConfigurer { -- -->

//页面跳转控制器,从请求直达视图

@Override

public void addViewControllers(ViewControllerRegistry registry) {

//配置页面控制:addViewController("请求的uri").指定他的视图setViewName(目标视图)

registry.addViewController("/welcome").setViewName("index");

}

@Override

public void addFormatters(FormatterRegistry registry) {

registry.addFormatter(new DeviceFormatter());

}

@Override

public void addInterceptors(InterceptorRegistry registry) {

//权限拦截器

AuthInterceptor authInterceptor = new AuthInterceptor();

registry.addInterceptor(authInterceptor)

.order(2)

.addPathPatterns("/article/**")

.excludePathPatterns("/article/query");

LoginInterceptor loginInterceptor = new LoginInterceptor();

}

}

step4:测试拦截器

POST http://localhost:8080/article/add

Content-Type: application/x-www-form-urlencoded

loginUser=lisi&title=Vue3

在这里插入图片描述

在这里插入图片描述

(二)、多个拦截器

增加一个验证登录用户的拦截器,只有 zhangsan,lisi,admin 能够登录系统。其他用户不可以。

两个拦截器登录的拦截器先执行,权限拦截器后执行,order()方法设置顺序,整数值越小,先执行。 step1:创建登录拦截器

step1:创建登录拦截器

<code>import jakarta.servlet.http.HttpServletRequest;

import jakarta.servlet.http.HttpServletResponse;

import org.springframework.util.StringUtils;

import org.springframework.web.servlet.HandlerInterceptor;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

public class LoginInterceptor implements HandlerInterceptor { -- -->

private List<String> permitUser = new ArrayList<>();

public LoginInterceptor() {

this.permitUser = Arrays.asList("zhangsan", "lisi", "admin");

}

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("=========LoginInterceptor执行了==========");

//获取登录用户名

String loginUser = request.getParameter("loginUser");

if(StringUtils.hasText(loginUser) && permitUser.contains(loginUser)){

return true;

}

return false;

}

}

step2:登记拦截器,设置顺序 order

@Override

public void addInterceptors(InterceptorRegistry registry) {

//权限拦截器

AuthInterceptor authInterceptor = new AuthInterceptor();

registry.addInterceptor(authInterceptor)

.order(2)

.addPathPatterns("/article/**")

.excludePathPatterns("/article/query");

LoginInterceptor loginInterceptor = new LoginInterceptor();

registry.addInterceptor(loginInterceptor)

.order(1)

.addPathPatterns("/**") // 拦截所有请求

.excludePathPatterns("/article/query")//排除/article/query 请求;

}

在这里插入图片描述

step3:测试拦截器

<code>POST http://localhost:8080/article/add

Content-Type: application/x-www-form-urlencoded

loginUser=lisi&title=Vue3

在这里插入图片描述

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。