Spring常用自定义配置
SpringBoot中使用SpringMVC非常方便,SpringBoot提供了大部分的MVC默认功能,并且需要自定义某部分功能也非常方便,在配置类中实现 WebMvcConfigurer 接口,根据需要重写方法即可:
1.自定义后端路径映射:
1.1 创建Config文件夹并创建AppConfig类
注意:
要添加@Configration且配置类要实现WebMvcConfigurer接口才能被Spring框架认定为配置类
1.2 通过generate快速生成配置方法:
点击Generate后点击Override Methods
出现重写方法之后,选择第一个
1.3 测试其效果:
@RequestMapping("/index2")
public String getIndex2(){
log.error("重定向");
return "redirect:/index.html";
}
其路由为mvc
但此时在浏览器中输入:http://localhost:8080/mvc/index2
加上api之后,就能够跳出页面了
2.自定义Controller拦截器
重写 addInterceptors 方法,实现时,需要指定拦截器,并配置需要拦截、不拦截的路径。在客户端发起请求时,如果路径最终匹配该规则,则执行拦截器中的接口方法。
用户拦截器–实现用户的授权:登录用户才能正常访问,否则只能访问登录和注册页面
1.创建一个拦截器,实现HandlerInterceptor接口,重写preHandle方法-用户自定义Session判断方法
2,SPringMVC的配置文件中设置拦截规则–
-哪些接口要拦截
-哪些接口不用拦截
2.1 创建一个拦截器:
public class LoginInterceptor implements HandlerInterceptor {
//自定义拦截方法,返回结果时boolean
//当为true的时候,表示方法可以链接后端接口,false表示不能访问
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){
HttpSession session = request.getSession();
if (session!=null && session.getAttribute(AppFinal.USERINFO_SESSIONKEY)!=null){
return true;
}
return false;
}
}
放在config包底下:
2.2 将拦截器添加到当前框架中:
并且指定哪些需要被拦截,这里addPathPatterns就是指定需要拦截的路由,excludePathPatterns是指定不拦截的路由;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).
addPathPatterns("/**")//拦截全部
.excludePathPatterns("/api/user/sayhi");//将该路由从拦截中剔除,不予拦截
}
放在AppConfig类底下表示将要配置到框架中:
2.2 测试:
此时已经不能访问user底下除了sayhi之外的路由
证明设置的拦截器已经成功拦截;
3.@ControllerAdvice–对数据的统一处理
@ControllerAdvice注解(控制器通知、控制器增强)定义的类,会自动注册为一个Bean对象,将扫描指定包中带@Controller注解的类:在客户端发起请求,映射到控制器方法时,结合其他注解或接口完成统一的增强功能
可以不指定扫描的包,对容器中所有@Controller生效
3.1 应用1异常的统一处理;:
此时需要结合@ExceptionHandler使用,可以实现控制器方法中出现异常后的统一异常处理。
先定义一个抛异常的服务,在 org.example.demo.controller.TestRestController 中,定义如下方法:
@RequestMapping("/test")
@RestController
public class TestController {
@GetMapping("/exception")
public Object exception(){
Map<Integer, String> map = new HashMap<>();
map.put(1, "张三");
map.put(2, "李四");
map.put(3, "王五");
int i = 1/0;
return map;
}
}
利用此方法来取得一个异常,
接下来定义一个异常总处理:
@ControllerAdvice
public class ErrorAdvice {
@ExceptionHandler(Exception.class)
@ResponseBody
public Object err(Exception e){
HashMap<String,Object> map = new HashMap<>();
map.put("status","-1");
map.put("data","");
map.put("msg",e.getMessage());
return map;
}
}
定义该类是负责统一处理出现的异常:@ControllerAdvice在这里就能够取得所有的Controller出现的异常,;
测试:此时就打印出我们出现异常的情况;
3.2 应用2:相应格式的统一封装
结合ResponseBodyAdvice接口,可以实现对控制器方法返回数据的统一封装。
首先创建一个类实现@ControllerAdvice
@ControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
@Autowired
private ObjectMapper objectMapper;
//注入容器中的ObjectMapper,SpringBoot默认使用jackson框架中的ObjectMapper完成json的序列化
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return true;//是否对responseBody增强
}
//响应的内容在返回客户端之前,会执行本方法,重写之后在返回
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
MediaType mediaType, Class aClass, ServerHttpRequest request,
ServerHttpResponse response) {
HashMap<String,Object> map = new HashMap<>();
map.put("status",0);
map.put("msg",o);
map.put("data",0);
//如果控制器方法返回类型为字符串,响应的Content-Type为text/plain,手动设置为json,并重写为序列化后的json字符串
if (o instanceof String){
try{
response.getHeaders().setContentType(mediaType.APPLICATION_JSON);
return objectMapper.writeValueAsString(map);
}catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException("json序列化失败");
}
}
return map;
}
}
此时我们知道所有Controller的方法的返回值都被统一了格式;
测试:
在TestController底下使用测试方法;
public class TestController {
@GetMapping("/exception")
public Object exception(){
Map<Integer, String> map = new HashMap<>();
map.put(1, "张三");
map.put(2, "李四");
map.put(3, "王五");
// int i = 1/0;
return map;
}
@RequestMapping("/method")
@ResponseBody
public Object method1(){
Object data = "method";
return data;
}
}
在前端访问时可以发现已经格式化为设置的mapjson序列;
再次测试另一个方法:
这里的msg对应了我们将要打印的map信息;