中央转发器(DispatcherServlet)
控制器
视图解析器
静态资源访问
消息转换器
格式化
静态资源管理
一、中央转发器
Xml无需配置
<servlet> <servlet-name>chapter2</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>chapter2</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
中央转发器被springboot自动接管,不再需要我们在web.xml中配置,我们现在的项目也不是web项目,也不存在web.xml,
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,
控制器
控制器Controller在springboot的注解扫描范围内自动管理。
视图解析器自动管理
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
ContentNegotiatingViewResolver:组合所有的视图解析器的;
曾经的配置文件无需再配
<bean id="de" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value="*.jsp"></property> </bean> |
源码:
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class)); resolver.setOrder(-2147483648); return resolver; } |
当我们做文件上传的时候我们也会发现multipartResolver是自动被配置好的页面
<form action="/upload" method="post" enctype="multipart/form-data"> <input name="pic" type="file"> <input type="submit"> </form> |
Controller
@ResponseBody @RequestMapping("/upload") public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){ String contentType = file.getContentType(); String fileName = file.getOriginalFilename(); /*System.out.println("fileName-->" + fileName); System.out.println("getContentType-->" + contentType);*/ //String filePath = request.getSession().getServletContext().getRealPath("imgupload/"); String filePath = "D:/imgup/"; try { this.uploadFile(file.getBytes(), filePath, fileName); } catch (Exception e) { // TODO: handle exception }
return "success"; }
public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception { File targetFile = new File(filePath); if(!targetFile.exists()){ targetFile.mkdirs(); } FileOutputStream out = new FileOutputStream(filePath+fileName); out.write(file); out.flush(); out.close(); } |
文件上传大小可以通过配置来修改
打开application.properties, 默认限制是10MB,我们可以任意修改
@ResponseBody @RequestMapping("/upload") public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){ String contentType = file.getContentType(); String fileName = file.getOriginalFilename(); /*System.out.println("fileName-->" + fileName); System.out.println("getContentType-->" + contentType);*/ //String filePath = request.getSession().getServletContext().getRealPath("imgupload/"); String filePath = "D:/imgup/"; try { this.uploadFile(file.getBytes(), filePath, fileName); } catch (Exception e) { // TODO: handle exception }
return "success"; }
public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception { File targetFile = new File(filePath); if(!targetFile.exists()){ targetFile.mkdirs(); } FileOutputStream out = new FileOutputStream(filePath+fileName); out.write(file); out.flush(); out.close(); } |
文件上传大小可以通过配置来修改
打开application.properties, 默认限制是10MB,我们可以任意修改

二、消息转换和格式化
Springboot自动配置了消息转换器

格式化转换器的自动注册

时间类型我们可以在这里修改

在配置文件中指定好时间的模式我们就可以输入了

三、springboot自动扩展SpringMVC
在实际开发中springboot并非完全自动化,很多跟业务相关我们需要自己扩展,springboot给我提供了接口。
我们可以来通过实现WebMvcConfigurer接口来扩展
public interface WebMvcConfigurer { default void configurePathMatch(PathMatchConfigurer configurer) { }
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) { }
default void configureAsyncSupport(AsyncSupportConfigurer configurer) { }
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) { }
default void configureMessageConverters(List<HttpMessageConverter<?>> converters) { }
default void extendMessageConverters(List<HttpMessageConverter<?>> converters) { }
default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { }
default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { }
@Nullable default Validator getValidator() { return null; }
@Nullable default MessageCodesResolver getMessageCodesResolver() { return null; } } |
3.1 在容器中注册视图控制器(请求转发)
创建一个MyMVCCofnig实现WebMvcConfigurer接口,实现一下addViewControllers方法,我们完成通过/tx访问,转发到success.html的工作
@Configuration
public class MyMVCCofnig implements WebMvcConfigurer{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/tx").setViewName("success");
}
}
3.2 注册格式化
用来可以对请求过来的日期格式化的字符串来做定制化。当然通过application.properties配置也可以办到。
@Override public void addFormatters(FormatterRegistry registry) { registry.addFormatter(new Formatter<Date>() { @Override public String print(Date date, Locale locale) { return null; } @Override public Date parse(String s, Locale locale) throws ParseException { return new SimpleDateFormat("yyyy-MM-dd").parse(s); } }); } |
3.3 消息转换器扩展fastjson
在pom.xml中引入fastjson
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> |
配置消息转换器,添加fastjson
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fc = new FastJsonHttpMessageConverter(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat); fc.setFastJsonConfig(fastJsonConfig); converters.add(fc); } |
在实体类上可以继续控制
public class User{private String username;private String password;private int age;private int score;private int gender;@JSONField(format = "yyyy-MM-dd")private Date date; |
3.4 拦截器注册
1.创建拦截器
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("前置拦截"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("后置拦截"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("最终拦截"); } } |
2. 拦截器注册
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/hello2"); } |