学习笔记2的回顾与补充:
1.SpringMVC默认返回的是视图,利用@ReponseBody注解让SpringMVC返回文本内容而非视图,这是主流的开发技术
2.@Controller注解与@ReponseBody注解可以合并为@RestController注解
3.RequestParam注解作用:
①实现非空效验,默认此参数必须填写;
②实现将前端的参数指定映射到后端的某个参数上
4.@RequestBody注解:
①默认参数不能为空
②取值时从body中获取
@RequestPart注解
这是一种文件注解,@RequestPart后传入的是MultipartFile多媒体文件类型
上传文件时,由于文件是file类型,因此需要在Postman的Body中以form-data方式选择传递File类型
增强注解:
@CookieValue注解(了解即可)
@RequestHeaders注解(了解即可)
浏览器中伪造Cookie信息,然后访问use/cookie
SpringMVC自定义配置
SpringBoot中使用SpringMVC非常方便,SpringBoo提供了大部分MVC默认功能,并且需要自定义某部分功能也非常方便,在配置类中实现WebMvcConfigurer接口,根据需要重写方法即可。
自定义后端路径映射:
c -> true 表示给所有的Controller添加api前缀
此时当我们访问url时必须加上前缀api,否则就无法访问
添加url添加api前缀后:
自定义Controller拦截器:
拦截器示意图:
重写addInterceptors方法,实现时需要指定拦截器,并配置需要拦截与不需要拦截的路径。当客户端发送请求时,如果路径最终匹配该规则,则执行拦截其中的接口方法。
举例:实现用户拦截器,对用户进行授权,当用户登录后才能访问,否则只能访问登录和注册。
1.先创建一个拦截器类实现HandlerInterceptor接口,重写preHandle方法(用户可以自定义session的判断方法)。
2.在SpringMVC的配置文件中设置拦截的规则(将拦截器对象传入),设置哪些后端接口需要拦截,哪些后端接口不需要拦截。
自定义拦截器代码:
public class LoginInterceptor implements HandlerInterceptor {
/**
* 自定义拦截方法 返回true时表示可以访问后端接口,返回false时表示无权访问后端接口
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
//判断session是否有值
if(session != null &&
session.getAttribute(AppFinal.USERINFO_SESSIONKEY) != null){
//表示用户已经登录
return true;
}
return true;
}
}
SpringMVC配置文件中设置拦截规则:
/**
* /**表示拦截所有的接口,包含了对静态页面的拦截
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/api/user/index")
.excludePathPatterns("/api/user/getcookie");
}
@ControllerAdvice
@ControllerAdvice注解(控制器通知、控制器增强)定义的类,会自动注册为一个Bean对象,将扫描指定包中带@Controller注解的类:在客户端发起请求,映射到控制器方法时,结合其他注解或接口完成统一的增强功能。
当然也可以不指定扫描的包,对容器中所有@Controller生效
应用1:统一异常处理
@ResponseBodyAdvice
应用2:数据统一封装格式返回
@ControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
@Autowired
private ObjectMapper objectMapper;
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return true; //表示是否对ResponseBody进行增强,返回true
}
@SneakyThrows
@Override
public Object beforeBodyWrite(Object o,
MethodParameter methodParameter,
MediaType mediaType,
Class aClass,
ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) {
HashMap<String, Object> map = new HashMap<>();
map.put("status",0);
map.put("data",o);
map.put("msg","");
if(o instanceof String){
//响应头中设置Json类型,当前方法返回给前端一个Json字符串
serverHttpResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
objectMapper.writeValueAsString(map);
}
return map;
}
}