1.什么是springmvc
springmvc全称是spring web mvc,是spring框架一部分,是一个mvc的框架,和struts2一样是一个表现层框架。
2.springmvc架构原理
1、 用户发送请求至前端控制器DispatcherServlet
2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器查找Handler。
3、 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、 DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
5、 HandlerAdapter调用处理器Handler
6、 Handler执行完成返回ModelAndView
7、 HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet
8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器,ViewReslover根据逻辑视图名解析View
9、 ViewReslover返回View
10、 DispatcherServlet对View进行渲染视图(即将模型数据填充至request域)。
11、 DispatcherServlet响应用户
3.springmvc入门程序
3.1 xml开发
新建一个web项目,导入jar包
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--解决post请求乱码--> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <!-- springmvc的前端控制器 --> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 加载springmvc的xml配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
新建springmvc.xml配置文件
<?xml version="1.0" encoding="uTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> <!-- 把controller的交给spring管理 --> <bean id="hello" class="com.gh.Hello"></bean> <!-- 配置适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 配置处理器映射器 --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/hello.do">hello</prop> </props> </property> </bean> </beans>
编写一个类实现controller接口
package com.gh; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class Hello implements Controller { @Override public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { ModelAndView modelAndView = new ModelAndView(); //设定一个视图跳转 modelAndView.setViewName("index.jsp"); return modelAndView; } }
启动Tomcat访问hello.do即可跳转到index页面
3.2 注解开发
新建springmvc2.xml配置文件
<?xml version="1.0" encoding="uTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> <mvc:annotation-driven></mvc:annotation-driven> <!--开启注解扫描--> <context:component-scan base-package="com.gh"/> <!--文件上传 --> <!-- Multipart解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置上传文件的最大尺寸为5MB --> <property name="maxUploadSize"> <value>5242880</value> </property> </bean> </beans>
编写controller层
package com.gh; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.UUID; @Controller public class ControllerTest { @RequestMapping("/show.do") public String show() { return "index.jsp"; } @RequestMapping("/show1.do") public String show2() { return "WEB-INF/login.jsp"; } @RequestMapping("/show3.do") public ModelAndView show3() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("view/register.html"); return modelAndView; } @RequestMapping("/show4.do") public String show4(User user, Model model) { model.addAttribute("as", "用户名或密码错误"); String username = user.getUsername(); model.addAttribute("msg", username); System.out.println(user); return "index.jsp"; } @RequestMapping("/show5.do") public void show5(@RequestParam("hobby") String[] ss) { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("sa", "asd"); for (int i = 0; i < ss.length; i++) { System.out.println(ss[i]); } } @RequestMapping("/show6.do") public void show6() throws Customer { Customer customer = new Customer("这是我自己的异常"); throw customer; } @RequestMapping("/show7.do") public void show7() { int a = 10 / 0; } @RequestMapping("/show8.do") public void show8() { int[] arr = new int[2]; arr[5] = 10; } @RequestMapping("/update.do") public void update(MultipartFile[] file) throws IOException { for (MultipartFile multipartFile : file) { String filename = multipartFile.getOriginalFilename(); int index = filename.lastIndexOf("."); String newName = filename.substring(index); String newFileName = UUID.randomUUID() + newName; File file1 = new File("E:\fileupload\", newFileName); multipartFile.transferTo(file1); } } }
配置前缀和后缀
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 指定视图路径前缀 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 指定视图路径后缀 --> <property name="suffix" value=".jsp" /> </bean>
4.默认支持类型
在controller方法形参中如下类型是可以直接绑定成功,springmvc框架给以下类型的参数直接赋值:
HttpServletRequest
通过request对象获取请求信息
HttpServletResponse
通过response处理响应信息
HttpSession
通过session对象得到session中存放的对象
Model/ModelMap
ModelMap是Model接口的实现类,通过Model或ModelMap向页面传递数据,
User user = itemService.findUserById(id);
model.addAttribute("user", user);
页面通过${user.XXXX}获取user对象的属性值。
使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap。
5.异常处理
5.1 业务系统中异常处理方法
异常类型包括可预期的异常、运行时异常,可预期的异常可以捕获的异常,程序员在编码阶段对预期的异常进行捕获处理,运行时异常不能预期知道的异常。程序员应该把重点放在可预期的异常处理上,对预期异常分类进行管理,定义不同的异常类型,根据类型进行有针对性的处理。对于运行时异常,应该在系统测试阶段加强测试,将运行时异常测试出来修改bug,从而降低运行时异常的出现概率。如果系统运行时出现运行时异常,一般提示“系统繁忙,,系统出错请与管理员联系。。。”
5.2 springmvc进行异常处理
springmvc提供异常处理器接口HandlerExceptionResolver,自定义异常处理器对系统中异常进行处理。
异常处理流程:
1、异常发生(在controller、service、dao)
2、在异常处理器中捕获异常
3、判断异常类型,根据异常类型有针对性去处理
如果异常类型是系统自定义的异常说明程序员在编码中有目的抛出预期的异常
调用异常类型的getMessage方法获取异常信息。
如果不是系统自定义的异常说明是运行时异常,提示用户“系统执行中出现错误请与管理员联系”
自定义异常处理器实现HandlerExceptionResolver重写resolveException方法
package com.gh; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class CustomExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) { ModelAndView modelAndView = new ModelAndView(); String message = e.getMessage(); if (e instanceof Customer) { modelAndView.addObject("msg", "我自己的异常"); } else { modelAndView.addObject("msg", "服务器繁忙,请稍后再试"); } System.out.println(message); modelAndView.setViewName("error.jsp"); return modelAndView; } }
6.文件上传
6.1 配置文件
在springmvc.xml中配置文件上传解析器
<!-- Multipart解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置上传文件的最大尺寸为5MB --> <property name="maxUploadSize"> <value>5242880</value> </property> </bean>
6.2 导入jar包
导入文件上传所需的jar包
6.3 编写前端页面
新建upload.jsp页面
method必须为post , enctype 指定为 multipart/form-data
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>文件上传</title> </head> <body> <form action="update.do" method="post" enctype="multipart/form-data"> <input type="file" name="file"/> <input type="file" name="file"/> <br/> <input type="submit"/> </form> </body> </html>
controller层接收上传文件进行操作
@RequestMapping("/update.do") public void update(MultipartFile[] file) throws IOException { for (MultipartFile multipartFile : file) { String filename = multipartFile.getOriginalFilename(); int index = filename.lastIndexOf("."); String newName = filename.substring(index); String newFileName = UUID.randomUUID() + newName; File file1 = new File("E:\fileupload\", newFileName); multipartFile.transferTo(file1); } }
7.重定向传递参数
使用RedirectAttributes来实现参数传递
attributes.addAttribute 重定向会把参数拼接在url上,这样不安全
attributes.addFlashAttribute 重定向,不会把参数拼接在url上,而是放在session中,当这次请求完成,session清除该条数据,不能用来获取,如果要获取必须使用@ModelAttribute("参数key")注解
8.springmvc对json的支持
json数据格式。
将请求结果以json格式输入好处:在页面使用js解析json比较方便
springmvc中通过@RequestBody注解实现将json数据转成java对象。内部使用jackson包将json转成java对象
springmvc中通过@ResponseBody注解实现将java对象转成json输出。
springmvc默认是使用Jackson,我们可以通过配置使用fastjson,并导入fastjson包就可以了
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json"/> <property name="features"> <array> <value>WriteMapNullValue</value> <value>WriteDateUseDateFormat</value> </array> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
9.springmvc拦截器
9.1 拦截器的作用
springmvc提供拦截器实现对Handler进行面向切面编程,可以Handler执行之前、之后、之中添加代码,这种方式就是切面编程。
拦截器相当 于一个过虑器,可以预处理、后处理等。
使用拦截器实现:
1、在Handler执行之前拦截校验用户权限,如果用户没有操作权限就不能继续执行Handler.
2、Handler执行完成后统一在拦截器中记录操作日志。
9.2 springmvc拦截器的定义
springmvc提供HanlderInterceptor接口,实现该 接口的就是拦截器。
package com.gh.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("pre"); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("post"); modelAndView.setViewName("register.jsp"); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("after"); } }
拦截器配置
<!--配置静态资源--> <mvc:resources mapping="js/**" location="/js/"/> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/test.do"/> <bean class="com.gh.interceptor.UserInterceptor"/> </mvc:interceptor> </mvc:interceptors>