SpringMVC学习笔记

    技术2025-04-18  8

    文章目录

    SpringMVC一、概述1.1 三层架构1.2 MVC1.3 SpringMVC 二、入门案例2.1 环境搭建2.2 工作流程 三、RequestMapping注解四、请求参数的绑定4.1 参数传递4.2 自定义类型转换 五、常用注解六、响应数据和结果视图6.1 字符串6.2 void6.3 ModelAndView 七、转发和重定向八、ResponseBody响应json数据九、文件上传9.1 普通文件上传9.2 分服务器上传文件 十、SpringMVC异常处理十一、SpringMVC中的拦截器

    SpringMVC

    一、概述

    1.1 三层架构

    开发框架一般基于两种形式,一种为C/S架构,即客户端/服务器;另一种为B/S架构,即浏览器服务器架构。在JavaEE开发中,几乎都是B/S架构。B/S架构中,系统标准的三层架构包括:表现层、业务层、持久层。

    表现层:即Web层,它负责接收客户端请求,向客户端响应结果,通常客户端使用HTTP协议请求web层,web需要接收HTTP请求,完成HTTP响应。表现成包括展示层和控制层,控制层负责接收请求,展示层负责结果的展示,表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。表现层的设计一般都使用MVC模型业务层:即service层。它负责业务逻辑处理,和我们开发项目的需求相关。web层依赖业务层,但是业务层不依赖web层。业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务的一致性,即事务应该放在业务层控制持久层:即dao层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。持久层就是和数据库交互,对数据库表进行增删改查

    1.2 MVC

    MVC即Model View Controller,是模型—视图—控制器的缩写,是一种用于设计创建Web应用程序表现层的模型

    Model:通常指的是我们的数据模型。作用一般用于封装数据View:通常指jsp或html,作用一般是展示数据,通常视图依据模型数据创建Controller:应用程序中处理用户交互的部分,作用一般是处理程序的逻辑

    1.3 SpringMVC

    SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于Spring FrameWork的后续产品。已经融合在Spring Web Flow里面。Spring框架提供了构建Web应用程序的全功能MVC模型。使用Spring可插入的MVC架构,从而在使用Spring进行WEB开发时,可以选择Spring的SpringMVC框架或其它MVC开发框架,如Strusts1,Struts2等SpringMVC是目前主流的MVC框架之一,并且随着Spring3.0的发布,全面超越Struts2,称为最优秀的MVC框架它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无需实现任何接口

    二、入门案例

    2.1 环境搭建

    依赖

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <!--版本锁定--> <spring.version>5.2.5.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> </dependencies>

    Web.xml

    <!--前端控制器配置--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--前端控制器加载配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

    SpringMVC.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> <!--开启注解扫描--> <context:component-scan base-package="ysw.controller"></context:component-scan> <!--视图解析器--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--文件所在目录--> <property name="prefix" value="/WEB-INF/pages/"/> <!--文件后缀名--> <property name="suffix" value=".jsp"/> </bean> <!--开启SpringMVC框架注解支持--> <mvc:annotation-driven/> </beans>

    2.2 工作流程

    三、RequestMapping注解

    出现的位置: 类上:代表请求URL的第一级目录,若不写就相当于服务的根目录方法上:请求URL的第二级访问目录 属性: value:用于指定请求的URL。和Path属性的作用一样method:用于指定请求方式params:用于指定限制请求参数的条件。支持简单表达式。要求请求参数的key和value必须和配置一样header:用于指定限制请求消息头的条件

    四、请求参数的绑定

    4.1 参数传递

    将参数的值赋给相应的属性

    可以在表单的name属性中填写相对应的属性名

    将参数封装到对象

    在表单的name属性中填写对象.属性名

    将参数封装到集合

    在表达name属性中填写集合.属性

    代码演示

    <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>param</title> </head> <body> <a href="param/testParam?username=hehe&password=123">请求参数绑定测试</a> <form action="/param/saveAccount" method="post"> <%--将参数值传递给相应属性--%> 姓名:<input type="text" name="username"><br> 密码:<input type="text" name="password"><br> 金额:<input type="text" name="money"><br> <%--将参数封装到对象--%> 用户姓名:<input type="text" name="user.name"><br> 用户年龄:<input type="text" name="user.age"><br> <input type="submit" value="提交"> </form> <form action="/param/saveAccount" method="post"> 姓名:<input type="text" name="username"><br> 密码:<input type="text" name="password"><br> 金额:<input type="text" name="money"><br> <%--将参数封装到集合--%> 用户姓名:<input type="text" name="list[0].name"><br> 用户年龄:<input type="text" name="list[0].age"><br> 用户姓名:<input type="text" name="map['one'].name"><br> 用户年龄:<input type="text" name="map['one'].age"><br> <input type="submit" value="提交"> </form> </body> </html>

    4.2 自定义类型转换

    public class StringToDate implements Converter<String, Date> { @Override public Date convert(String s) { if (s == null) { throw new RuntimeException("传入参数错误!!"); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { return simpleDateFormat.parse(s); } catch (ParseException e) { throw new RuntimeException("格式转换错误!!"); } } }

    配置文件

    <!--配置自定义类型转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="ysw.Utils.StringToDate"/> </set> </property> </bean> <!--开启SpringMVC框架注解支持--> <mvc:annotation-driven conversion-service="conversionService"/>

    五、常用注解

    RequestParam

    作用:将请求中指定名称的参数给控制器中的形参赋值属性:value:请求参数中的名称;required:请求参数中必须提供此参数。默认值为True。表示必须提供

    RequestBody

    作用:获取请求体中的内容,直接使用会得到key=value属性:required:是否必须有请求体。默认为true。当取值为true时get请求会报错。如果取值为false,get请求得到null

    PathVariable

    作用:拥有绑定url中的占位符。例如“rul中有/delete/{id},{id}就是占位符属性:value:指定url中的占位符名称rest父类风格的URL优点: 结构清晰符合标准易于理解扩展方便

    RequestHeader

    获取请求头的值

    CookieValue

    获取Cookie的值

    ModelAttribute

    可以用于修饰方法和参数出现在方法上,表示当前方法会在控制器的方法执行前先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法出现在参数上,获取指定的数据给参数赋值

    SessionAttributes

    用于多次执行控制器方法间的参数共享属性:value:用于指定存入的属性名称;type:用于指定存入的数据类型作用在类上 @SessionAttributes(value = {"msg"}) @Controller @RequestMapping("/param") public class ParamController { @RequestMapping("/testSessionAttributes") public String testSessionAttributes(Model model){ model.addAttribute("msg","hello"); return "success"; } }

    六、响应数据和结果视图

    6.1 字符串

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testString") public String testString(Model model){ System.out.println("testString!!!"); User user = new User(); user.setName("Tom"); user.setPassword("1234"); user.setAge(18); model.addAttribute("user",user); return "success"; } } 在页面可以通过${user.name}获取到值

    6.2 void

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testVoid") public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("testVoid!!!"); //转发 // request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response); //重定向 // response.sendRedirect(request.getContextPath()+"/index.jsp"); //向页面输出数据 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html"); response.getWriter().print("你好!!"); return; } }

    6.3 ModelAndView

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testModelAndView") public ModelAndView testModelAndView() { ModelAndView modelAndView = new ModelAndView(); User user = new User(); user.setAge(19); user.setPassword("1234"); user.setName("Job"); modelAndView.addObject("user", user); //指定跳转到某个页面 modelAndView.setViewName("success"); return modelAndView; } }

    七、转发和重定向

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/forwardOrRedirect") public String forwardOrRedirect() { System.out.println("转发或重定向!!"); //转发 //return "forward:/WEB-INF/pages/success.jsp"; //重定向 return "redirect:/index.jsp"; } }

    八、ResponseBody响应json数据

    首先需要配置哪些静态资源不需要被控制器拦截(springmvc.xml)

    <!--告诉前端控制器哪些资源不需要拦截--> <mvc:resources mapping="/css/**" location="/css/"/> <mvc:resources mapping="/images/**" location="/images/"/> <mvc:resources mapping="/js/**" location="/js/"/>

    导入Jar包

    <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.10.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.10.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.3</version> </dependency>

    测试类

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testAjax") @ResponseBody public User testAjax(@RequestBody User user) { System.out.println("testAjax执行!!!"); //客户端发送Ajax的请求,传json字符串,后端将json字符串封装到User对象中 System.out.println(user.toString()); user.setName("Lily"); user.setAge(30); //返回json数据 return user; } }

    九、文件上传

    9.1 普通文件上传

    借助第三方组件上传文件,导入依赖

    <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.webjars.npm</groupId> <artifactId>commist</artifactId> <version>1.0.0</version> </dependency>

    SpringMVC上传文件,配置文件解析器(springmvc.xml)

    <!--文件解析器--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--允许上传的最大文件大小--> <property name="maxUploadSize" value="10485760"/> </bean>

    测试

    @Controller @RequestMapping("/user") public class UserController { /** * @Param [req, upload] * @return java.lang.String * @Date 9:03 2020/7/4 * @Description: //TODO **/ @RequestMapping("/fileupload1") public String fileupload1(HttpServletRequest req, MultipartFile upload) throws IOException { System.out.println("文件上传!!"); String path = req.getSession().getServletContext().getRealPath("/uploads/"); File file = new File(path); if (!file.exists()) { //创建文件夹 file.mkdirs(); } //获取文件名称 String filename = upload.getOriginalFilename(); //将文件名称设置为唯一值 String replace = UUID.randomUUID().toString().replace("-", ""); filename = replace + "_" + filename; //完成文件上传 upload.transferTo(new File(path, filename)); return "success"; } }

    9.2 分服务器上传文件

    导入jar包

    <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.19.4</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>1.19.4</version> </dependency>

    代码演示

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/fileupload") public String fileupload2(MultipartFile upload) throws IOException { System.out.println("文件上传!!"); //定义上传文件服务路径 String path = "http://localhost:xxxx/xxxx/"; //获取文件名称 String filename = upload.getOriginalFilename(); //将文件名称设置为唯一值 String replace = UUID.randomUUID().toString().replace("-", ""); filename = replace + "_" + filename; //创建客户端对象 Client client = Client.create(); //和文件服务器进行连接 WebResource resource = client.resource(path + filename); //上传文件 resource.put(upload.getBytes()); return "success"; } }

    十、SpringMVC异常处理

    异常测试 @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testException") public String testException() throws SysException { try { //模拟异常 int a = 10 / 0; } catch (Exception e) { //打印异常信息 e.printStackTrace(); //抛出自定义异常 throw new SysException("出现错误!!!"); } return "success"; } } 自定义异常 public class SysExceptionResolver implements HandlerExceptionResolver { /** * @return org.springframework.web.servlet.ModelAndView * @Param [httpServletRequest, httpServletResponse, o, e] * @Date 9:48 2020/7/4 * @Description: 处理异常 **/ @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { //获取异常对象 SysException ex = null; if (e instanceof SysException) { ex = (SysException) e; } else { ex = new SysException("系统正在维护……"); } //创建ModelAndView对象 ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("errorMsg", ex.getMessage()); modelAndView.setViewName("error"); return modelAndView; } } 配置异常处理器 <!--配置异常处理器--> <bean id="sysExceptionResolver" class="ysw.exception.SysExceptionResolver"/>

    十一、SpringMVC中的拦截器

    自定义类实现HandlerInterceptor接口

    /** * @Description: TODO * @Author YunShuaiWei * @Date 2020/7/4 10:46 * @Version **/ public class MyInterceptor implements HandlerInterceptor { /** * @return boolean * true:放行,执行下一个拦截器,若没有,则执行controller中的方法 * false:不放行 * @Param [request, response, handler] * @Date 10:47 2020/7/4 * @Description: 预处理,controller方法执行前 **/ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("……"); return true; } /** * @return void * @Param [request, response, handler, modelAndView] * @Date 10:58 2020/7/4 * @Description: Controller执行后执行的方法 **/ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle……"); request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); } /** * @return void * @Param [request, response, handler, ex] * @Date 10:59 2020/7/4 * @Description: 最后执行的方法, 即跳转到success.jsp之后会执行该方法 **/ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion……"); } }

    配置拦截器

    <!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!--要拦截的具体方法--> <mvc:mapping path="/user/*"/> <!--不要拦截的方法 <mvc:exclude-mapping path=""/>--> <bean class="ysw.interceptor.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
    Processed: 0.010, SQL: 9