中央转发器(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" ); }