零配置文件搭建SpringMvc
SpringMvc 流程原理
(1)用户发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet通过HandlerAdapter处理器适配器调用处理器;
(5)执行处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。
Spring MVC的主要组键
(1)前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果 相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
(2)处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的URL来查找Handler
(3)处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
(4)处理器Handler(需要程序员开发)
(5)视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析 根据视图逻辑名解析成真正的视图(view)
(6)视图View(需要程序员开发jsp)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
零配置文件搭建SpringMVC Start
1、pom文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.wisely</groupId> <artifactId>highlight_springmvc4</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <!-- Generic properties --> <java.version>1.7</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- Web --> <jsp.version>2.2</jsp.version> <jstl.version>1.2</jstl.version> <servlet.version>3.1.0</servlet.version> <!-- Spring --> <spring-framework.version>4.1.5.RELEASE</spring-framework.version> <!-- Logging --> <logback.version>1.0.13</logback.version> <slf4j.version>1.7.5</slf4j.version> </properties> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring-framework.version}</version> </dependency> <!-- 其他web依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>${jsp.version}</version> <scope>provided</scope> </dependency> <!-- Spring and Transactions --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring-framework.version}</version> </dependency> <!-- 使用SLF4J和LogBack作为日志 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>${logback.version}</version> </dependency> <!--对json和xml格式的支持 --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.5.3</version> </dependency> <!-- file upload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- 非必需,可简化IO操作 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring-framework.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project>
2、MVC 配置Bean
import com.wisely.mypractice.interceptor.MyInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.*; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration //开启Mvc功能 @EnableWebMvc //扫包 @ComponentScan("com.wisely.mypractice") public class MyMvcConfig extends WebMvcConfigurerAdapter { //配置视图解析器 @Bean public InternalResourceViewResolver viewResolver(){ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/classes/views/"); viewResolver.setSuffix(".jsp"); viewResolver.setViewClass(JstlView.class); return viewResolver; } //配置静态文件路径(直接访问) @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/inde/"); } //将拦截器Bean纳入spring管理 @Bean public MyInterceptor demoInterceptor(){ return new MyInterceptor(); } //配置 拦截器 @Override public void addInterceptors(InterceptorRegistry registry){ registry.addInterceptor(demoInterceptor()); } //设置文件上传最大字节 @Bean public MultipartResolver multipartResolver(){ CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(1000000); return multipartResolver; } }
3、拦截器Bean
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){ long startTime = System.currentTimeMillis(); request.setAttribute("startTime",startTime); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){ long startTime = (Long)request.getAttribute("startTime"); request.removeAttribute("startTime"); long endTime = System.currentTimeMillis(); System.out.println("本次请求处理时间为:"+ new Long(endTime-startTime) + "ms"); request.setAttribute("handlingTime",endTime - startTime); } }
3、配置 WebApplicationInitializer 实现类 (项目启动会自动加载该类的实现类)
import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; public class WebInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(MyMvcConfig.class); context.setServletContext(servletContext); ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher",new DispatcherServlet(context)); //映射路径 servlet.addMapping("/"); servlet.setLoadOnStartup(1); } }
4、拦截器
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor extends HandlerInterceptorAdapter { //请求前执行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){ long startTime = System.currentTimeMillis(); request.setAttribute("startTime",startTime); return true; } //请求后执行 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){ long startTime = (Long)request.getAttribute("startTime"); request.removeAttribute("startTime"); long endTime = System.currentTimeMillis(); System.out.println("本次请求处理时间为:"+ new Long(endTime-startTime) + "ms"); request.setAttribute("handlingTime",endTime - startTime); } }
5、全局配置
import org.springframework.ui.Model; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.ModelAndView; @ControllerAdvice public class MyAdvice { //异常处理类( Exception.class 异常类型 ) 可以定义多个 @ExceptionHandler(value = Exception.class) public ModelAndView exception(Exception exception, WebRequest request){ ModelAndView modelAndView = new ModelAndView("error"); modelAndView.addObject("errorMessage",exception.getMessage()); return modelAndView; } //所有RequestMapping方法上 可以通过 ModelAttribute 形式获取值 @ModelAttribute public void addAttributes(Model model){ model.addAttribute("msg","额外信息"); } //忽略请求属性(只针对用Bean接受) @InitBinder public void initBinder(WebDataBinder webDataBinder){ webDataBinder.setDisallowedFields("id"); } }
6、Controller 控制器
import com.wisely.mypractice.domain.MyObj; import org.apache.commons.io.FileUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; @Controller public class HelloController { @RequestMapping("/index") public String hello(){ return "index"; } @RequestMapping("/uploadToPage") public String uploadToPage(){ return "upload"; } @RequestMapping(value = "upload",method = RequestMethod.POST) public String upload(MultipartFile file){ try{ FileUtils.writeByteArrayToFile(new File("D:\test\"+file.getOriginalFilename()),file.getBytes()); return "ok"; }catch (IOException e){ e.printStackTrace(); return "wrong"; } } @RequestMapping("/advice") public String getSomething(@ModelAttribute("msg") String msg, MyObj obj){ System.out.println("id:" + obj.getId()); System.out.println("name:" + obj.getName()); throw new IllegalArgumentException("非常抱歉,参数有误来自@ModelAttribute:" + msg); } }
TODO:
1)、页面我没有进行 copy 到帖子里 自己编写一些简单页面就可以了
2)、代码暂时没放到 GitHab 上 我研究一下 弄好了会修改帖子给出下载路径(只要配上页面 代码完全是好用的哦 )
3)、个人 QQ 1036943655 有什么技术上见解 可以一起互相学习 毕竟本人会的也不多
4)、所有知识点借鉴于 Spring Boot 实战 (书)