JavaEE之Spring MVC框架
一、Spring MVC 简介
-
简介
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
-
模型封装了应用程序数据,并且通常它们由 POJO 组成。
-
视图主要用于呈现模型数据,并且通常它生成客户端的浏览器可以解释的 HTML 输出。
-
控制器主要用于处理用户请求,并且构建合适的模型并将其传递到视图呈现。
DispatcherServlet
Spring Web 模型-视图-控制(MVC)框架是围绕 DispatcherServlet 设计的,DispatcherServlet 用来处理所有的 HTTP 请求和响应。Spring Web MVC DispatcherServlet 的请求处理的工作流程如下图所示:

-
收到一个 HTTP 请求后,DispatcherServlet 根据 HandlerMapping 来选择并且调用适当的控制器。
-
控制器接受请求,并基于使用的 GET 或 POST 方法来调用适当的 service 方法。Service 方法将设置基于定义的业务逻辑的模型数据,并返回视图名称到 DispatcherServlet 中。
-
DispatcherServlet 会从 ViewResolver 获取帮助,为请求检取定义视图。
-
一旦确定视图,DispatcherServlet 将把模型数据传递给视图,最后呈现在浏览器中。
-
-
Spring MVC和Spring的关系

二、Spring MVC 入门程序
-
导入jar包

-
配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>
contextConfigLocation
</param-name>
<param-value>
classpath:spring-mvc.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
-
配置springmvc核心配置文件
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--配置后端控制器(controller) -->
<bean name="/hello" class="cn.qn.controller.HomeController"></bean>
<!--配置处理器映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!--配置处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter">
</bean>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
-
新建后端控制器(HomeController)
public class HomeController extends AbstractController{
-
配置tomcat,启动项目

三、Spring MVC 注解使用
-
使用注解的后端处理控制器
-
开启注解扫描(此处附处理器映射器和适配器的其他配置方式)
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 处理器映射器和处理器适配器的配置可以省略
springMVC框架已经做了处理
-->
<!-- 配置处理器映射器 -->
<!-- <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>-->
<!-- 使用最新版的 处理器映射器
若使用最新版的,则处理器映射器和处理器适配器都要配置最新版的
-->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>-->
<!-- 配置处理器适配器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>-->
<!--使用新版的处理器适配器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>-->
<!-- springmvc自动配置最新的处理器映射器和处理器适配器 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置后端控制器(controller) -->
<!-- <bean name="/hello" class="cn.edu.dgut.controller.HelloController"></bean>-->
<!-- 开启扫描 -->
<context:component-scan base-package="cn.edu.dgut.controller"></context:component-scan>
<!-- 配置视图解析器 若在控制器类写了完整路径,则不用配置 -->
<!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>-->
</beans>
四、Spring MVC 参数绑定
-
默认支持普通servlet的方式
-
简单类型(参数名要与jsp中name属性值对应)
-
实体对象(jsp中name属性名要与实体中属性对应)
五、Spring MVC 控制器返回值
-
ModelAndView
modelAndView.addObject("itemList", list); //指定返回页面的数据 modelAndView.setViewName("itemList"); //指定返回的页面
-
String(推荐使用)
返回普通字符串,就是页面去掉扩展名的名称, 返回给页面数据通过Model来完成
-
普通跳转(jsp页面)
@RequestMapping(value="/updateProduct") public String updateProduct(Product product,Model model) throws ServletException { productservice.update(product); model.addAttribute("xxx",”xxxx”); return " productItem "; } -
请求转发(请求)
@RequestMapping(value="/updateProduct") public String updateProduct(Product product,Model model) throws ServletException { productservice.update(product); model.addAttribute("msg","今天天气不错呀"); return "forward:list"; } -
重定向(请求)
@RequestMapping(value="/updateProduct") public String updateProduct(Product product,Model model) throws ServletException { productservice.update(product); model.addAttribute("msg","今天天气不错呀"); //return "forward:list"; return "redirect:list"; }
-
-
void(破坏了springMvc的结构,不建议使用)
-
可以使用request.setAttribut 来给页面返回数据
-
可以使用request.getRquestDispatcher().forward()来指定返回的页面
-
如果controller返回值为void则不走springMvc的组件,所以要写页面的完整路径名称
-
六、Spring MVC 乱码问题
-
解决post乱码问题(在web.xml中加入过滤器配置)
<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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
get乱码问题
-
修改tomcat配置文件添加编码与工程编码一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
-
也可以对参数进行重新编码
String username= new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8");
-
七、Spring MVC 自定义转换器
-
编写自定义转换器类
public class CustomerConveter implements Converter<String, Date>{ @Override public Date convert(String source) { try { Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(source); return date; } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
-
在springmvc.xml中配置自定义转换器
<!--配置自定义转换器 --> <bean name="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.shop.conveter.CustomerConveter"></bean> </set> </property> </bean>
-
将配置好的自定义转换器挂载(springmvc.xml)
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
八、Spring MVC 文件上传
-
准备jar包

-
jsp客户端准备
-
提供一个File上传表单控件

-
指定表单类型
!-- 上传图片是需要指定属性 enctype="multipart/form-data" --> <form id="itemForm" action="${pageContext.request.contextPath}/updateProduct" method="post" enctype="multipart/form-data">
-
-
配置SpringMVC文件上传
<!-- 配置文件上传 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 配置上传图片最大上限 5M --> <property name="maxUploadSize"> <value>5242880</value> </property> </bean>
-
上传后台代码实现
@RequestMapping(value="/updateProduct") public ModelAndView updateProduct(MultipartFile pictureFile,Product product) throws IllegalStateException, IOException { if(!pictureFile.isEmpty()) { // 获取图片的完整路径 String fileName = pictureFile.getOriginalFilename(); // 使用随机生成的字符串 + 原图片的扩展名 组成 String NewFileName = UUID.randomUUID().toString()+fileName.substring(fileName.lastIndexOf(".")); // 将图片保存在服务器 (硬盘) pictureFile.transferTo(new File("D:\\images\\"+NewFileName)); // 保存在数据库 product.setPic(NewFileName); } //product.setCreatetime(new Date()); //执行修改功能 productservice.update(product); ModelAndView mv = new ModelAndView(); mv.setViewName("test"); return mv; }
九、Spring MVC json数据交互
-
导入jar包

-
配置json转换器(如果使用
<mvc:annotation-driven />则不用配置以下的内容)<!--注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean> </list> </property> </bean>
-
编写前端
-
导入jquery文件
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.4.4.min.js"></script> -
编写Ajax方法
<script type="text/javascript"> //请求json响应json function sendjson() { $.ajax({ type:"post", url:"${pageContext.request.contextPath}/sendjson", contentType:"application/json;charset=utf-8", data:'{"name":"iphoneX爆款手机","price":8000.9}', success:function(data){ alert(data); } }); } </script> <input type="button" value="发送json" onclick="sendjson()">
-
-
controller编写
@RequestMapping(value="/sendjson") @ResponseBody //将对象转成json格式 public Product sendjson(@RequestBody Product product) { System.out.println("product:"+product); return product; }
十、Spring MVC RESTful支持
-
RESTful概念
Representational State Transfer,即表述性转移,是一种软件架构的风格(一个规范),不是一门技术。
-
REST和传统方式对比
-
传统方式
https://movie.douban.com/subject?id=26416062
-
restful风格
https://movie.douban.com/subject/26416062
-
-
REST风格好处
-
使用传统url方式进行参数参数的时候,如果需要传递参数,那么中文乱码很头疼
-
n 传统url方式,对于各大搜索引擎的收录,并不是很友好,但是rest风格方式,搜索引擎就更加酷爱
-
-
RESTful使用
<%-- <td><a href="${pageContext.request.contextPath }/itemEdit?id=${item.id}">修改</a></td> --%> <td><a href="${pageContext.request.contextPath }/itemEdit/${item.id}">修改</a></td>@RequestMapping(value="/itemEdit/{id}") public ModelAndView getProductById(@PathVariable("id")Integer aa,HttpServletRequest req, HttpServletResponse response, HttpSession ss) { //String id = req.getParameter("id"); //Product product = productservice.getProductById(Integer.parseInt(id)); Product product = productservice.getProductById(aa); ...
十一、Spring MVC 异常处理(自定义异常)
-
新建一个自定义异常类
public class MyException extends Exception{ private String msg; public MyException(String msg) { super(); this.msg = msg; } public MyException() { super(); // TODO Auto-generated constructor stub } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } -
定义异常处理器
public class GoableException implements HandlerExceptionResolver{ @Override public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse response, Object handler, Exception exception) { String res = "出bug了,请联系管理员"; if(exception instanceof MyException) { res = ((MyException)exception).getMsg(); } ModelAndView mv = new ModelAndView(); mv.addObject("msg", res); mv.setViewName("error"); return mv; } }
-
测试方法
@RequestMapping(value="/list") public void getList(HttpServletRequest req,HttpServletResponse response) throws ServletException, IOException, MyException { if(true) { throw new MyException("您没有找到一些商品哈哈哈"); } // 制造异常情况 int i = 1/0; List<Product> list = productservice.getProductList();
十二、Spring MVC 拦截器
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
-
定义拦截器
Public class HandlerInterceptor1 implements HandlerInterceptor{ /** * controller执行前调用此方法 * 返回true表示继续执行,返回false中止执行 * 这里可以加入登录校验、权限拦截等 */ @Override Public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub Return false; } /** * controller执行后但未返回视图前调用此方法 * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示 */ @Override Public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } /** * controller执行后且视图返回后调用此方法 * 这里可得到执行controller时的异常信息 * 这里可记录操作日志,资源清理等 */ @Override Public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub } }
-
配置拦截器(springmvc.xml)
-
针对某种mapping配置拦截器
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="handlerInterceptor1"/> <ref bean="handlerInterceptor2"/> </list> </property> </bean> <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/> <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>
-
针对所有mapping配置全局拦截器
<!--拦截器 --> <mvc:interceptors> <!--多个拦截器,顺序执行 --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.shop.springmvc.filter.HandlerInterceptor1"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.shop.springmvc.filter.HandlerInterceptor2"></bean> </mvc:interceptor> </mvc:interceptors>
-
本文是学习spring mvc的笔记总结,欢迎大家批评指正,有什么问题可以评论区交流。
参考链接:https://www.w3cschool.cn/wkspring/9pf81ha5.html

浙公网安备 33010602011771号