MVC 和Spring MVC
我们都知道常说的MVC指的是
Model + View + Controller(数据模型 + 视图+ 控制器)
三层架构指的是:(展现层 + 应用层 + 数据访问层)
但是Spring MVC却不是指的上面的三层架构而是将展现层拆分成了新的三层架构
M :指的是数据模型(Model类)
V :指的是视图页面(JSP,Thymeleaf等)
C :指的是控制器(@Controller注解的类)
1.配置项目支持SpringMVC
除了需要在pom.xml中依赖对应的jar包,我们还需要完善web项目的目录结构,在代码层面上当我们使用idea创建一个支持SpringMVC的web项目的时候,会自动生成一个继承SpringbootServletInitializer的类,用来提供配置Servlet3.0配置的接口,替代web.xml的位置
如果项目没有实现这个类,那么久必须要使用web.xml进行相关的web项目配置
DispatcherServlet :分发器 用来将请求对应到指定的view视图
2.常用注解
@Controller: 声明一个控制器
@RequestMapping: 映射web请求(将方法和url对应起来)
@ResponseBody: 将返回值放到response中,而不是映射到对应的页面上
@RequestBody: 允许请求的参数放到request体中,而不是直接链接到URL后面、
@PathValiable: 用来接收参数,例如:news/001 ,可接受001作为参数
3.SpringMVC的自定义配置
SpringMVC的自定义配置在SpringMVC5.0之前需要自定义一个配置类继承WebMvcConfigurerAdapter,在SpringMVC5.0之后被WebMvcConfigurationSupport代替了
WebMvcConfigurationSupport是SpringMVC的全局自定义配置门面类
添加自定义拦截器:
自定义配置类需要添加自定义拦截器可以实现addInterceptors()方法,如下所示:
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(wapInterceptor()).addPathPatterns("/wap/**");
}
自定义拦截器需要继承HandlerInterceptor
实现postHandler和preHandler方法实现对请求处理之前和之后的拦截操作
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3)
throws Exception {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
return true; //通过拦截器成功
}
添加自定义页面转向
@Override
protected void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index").setViewName("/index");
super.addViewControllers(registry);
}
上面代码添加了页面转向,当访问url为index的时候会跳转到index页面,可以用来统一管理特定页面转向
还有很多其他的配置,例如路径参数配置等
4.控制器controller的全局配置?
(1)全局捕获controller异常
可以使用注解@ControllerAdvice给controller设置全局的配置
在controller的全局配置类中我们可以使用注解@ExceptionHandler来处理全局的controller异常
如下所示:
@ExceptionHandler(UndeclaredThrowableException.class)
@ResponseBody
public Object credentials(UndeclaredThrowableException e) {
log.info("权限异常!", e);
return ResultUtils.error(AuthResultEnum.PERMISSION_ERROR);
}
上面代码使用注解@ExceptionHandler声明了可以处理UndeclaredThrowableException异常
(2)配置绑定前台请求参数
注解@InitBinder可以用来设置WebDataBinder,用来自动绑定前台请求参数到model中
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Object.class, new ObjectNullEditor());
}
(3)给请求添加全局的参数
使用注解@ModelAttributes可以给所有的model添加参数,如下所示:
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("from","app");
}
5.SpringMVC文件上传
在spring控制器(controller)中通过MultipartFile 来接收文件,通过MultipartFile[] 来接收多个文件
6.自定义消息转换器HttpMessageConverter
HTTPMessageConverter是用来处理request和response里的数据的,spring内置了大量的HTTPMessageConverter实现类,例如StringHTTPMessageConverter,MessageJackson2HttpMessageConverter
每一个HTTPMessageConverter的实现类都需要声明自己处理的是什么消息,例如StringHTTPMessageConverter就是专门用来处理String消息的转换器,如下所示:
public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
public boolean supports(Class<?> clazz) {
return String.class == clazz;
}
protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage){
Charset charset = this.getContentTypeCharset(inputMessage.getHeaders().getContentType());
return StreamUtils.copyToString(inputMessage.getBody(), charset);
}
protected Long getContentLength(String str, @Nullable MediaType contentType) {
Charset charset = this.getContentTypeCharset(contentType);
return (long)str.getBytes(charset).length;
}
support方法判断消息是否属于自己的处理范围
在继承WebMvcConfigurationSupport类的SpringMVC配置类中重载configureMessageConverters方法,可以添加自定义的消息转换器,如下所示:
@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.addAll(this.converters);
}
7.SpringMVC测试
为了模拟SpringMVC请求以使得我们可以不用启动tomcat就可以测试代码,我们需要使用一些模拟框架,例如:MockMVC