当前位置: 首页 > web >正文

SpringMVC框架详解与实践指南

文章目录

  • 一、三层架构与MVC模型
    • 1. 三层架构
    • 2. MVC模型
  • 二、SpringMVC入门案例
    • 1. 环境搭建
    • 2. 核心配置
    • 3. 编写Controller
  • 三、执行流程与组件分析
  • 四、RequestMapping注解
  • 五、请求参数绑定
    • 1. 基本类型与对象绑定
    • 2. 嵌套对象与集合绑定
  • 六、中文乱码解决方案(前端传到后端)
    • 1. String转字节流(不推荐)
    • 2. Servlet中配置编码
    • 3. 过滤器(Filter)统一处理
      • 方案一:Spring框架提供的过滤器(推荐)
      • 方案二:自定义过滤器(处理GET/POST)
  • 七、自定义类型转换器
    • 1.使用DateTimeFormat注解的方式
    • 2.自定义类型转换器
  • 八、SpringMVC常用注解详解
    • 1. @RequestParam注解
    • 2. @RequestBody注解
    • 3. @PathVariable注解与Restful风格URL
    • 4. @RequestHeader注解
    • 5. @CookieValue注解
  • 总结


一、三层架构与MVC模型

1. 三层架构

表现层(WEB层):负责与客户端交互,采用MVC设计模型。

业务层:处理具体业务逻辑。

持久层:操作数据库。

2. MVC模型

Model:数据模型(如JavaBean),用于封装数据。

View:视图层(如JSP/HTML),展示数据。

Controller:控制器,接收请求并处理逻辑。

二、SpringMVC入门案例

1. 环境搭建

Maven依赖配置:

<properties><spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><!-- Servlet API --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version><scope>provided</scope></dependency>
</dependencies>

2. 核心配置

web.xml:

<!-- 配置DispatcherServlet -->
<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>*.do</url-pattern>
</servlet-mapping>

springmvc.xml:

<!-- 扫描Controller包 -->
<context:component-scan base-package="cn.tx"/>
<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/>
</bean>

3. 编写Controller

@Controller
public class HelloController {@RequestMapping("/hello.do")public String sayHello() {System.out.println("请求处理中...");return "suc"; // 跳转到 /WEB-INF/pages/suc.jsp}
}

三、执行流程与组件分析

  1. DispatcherServlet:前端控制器,接收请求。
  2. HandlerMapping:映射请求到具体方法。
  3. HandlerAdapter:调用处理器方法。
  4. ViewResolver:解析视图名称。
  5. View:渲染结果并响应。

四、RequestMapping注解

RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系。
RequestMapping注解可以作用在方法和类上。

作用在类上:第一级的访问目录
作用在方法上:第二级的访问目录
细节:路径可以不编写 / 表示应用的根目录开始

RequestMapping的属性

  • path 指定请求路径的url
  • value value属性和path属性是一样的(可隐藏)
  • method 指定该方法的请求方式
method主要应用
get查询
post增加
delete删除
put修改
  • params 指定限制请求参数的条件
    例:
@Controller
@RequestMapping("/user")
public class UserController {@RequestMapping(path = "/save.do",method = {RequestMethod.GET},params = "username")public String save(){System.out.println("保存角色...");return "suc";}}

五、请求参数绑定

1. 基本类型与对象绑定

JSP表单:

<form action="/user/save.do" method="post">姓名:<input type="text" name="username">年龄:<input type="text" name="age"><input type="submit" value="提交">
</form>

Controller接收:

@RequestMapping("/save.do")
public String saveUser(String username, Integer age) {System.out.println("用户名:" + username + ",年龄:" + age);return "suc";
}

2. 嵌套对象与集合绑定

JavaBean:

public class User {private String username;private Address address;    // 嵌套对象private List<Address> list; // List对象集合private List<Strig> list1; // List字符串集合private Map<String, String> map; // Map集合
}

JSP表单:

<!-- 嵌套对象 -->
<input type="text" name="address.city">
<!-- List集合 -->
<input type="text" name="list[0].city">
<input type="text" name="list[1].city">
<input type="text" name="list1[0]">
<input type="text" name="list1[1]">
<!-- Map集合 -->
<input type="text" name="map['key1']">
<input type="text" name="map['key2']">

Controller接收:

 @RequestMapping("/save1.do")public String save1(User user){System.out.println("user对象:"+user);return "suc";}

六、中文乱码解决方案(前端传到后端)

1. String转字节流(不推荐)

适用场景:GET请求参数乱码(不推荐,仅作临时方案)
实现原理:将接收到的参数从默认的ISO-8859-1编码转换为UTF-8

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");

缺点:需逐个参数处理,代码冗余,无法覆盖所有请求类型。

2. Servlet中配置编码

适用场景:POST请求的表单数据
实现原理:在Servlet的doPost方法中设置request和response编码。

// 在Servlet中配置
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");// 其他处理逻辑
}

配置位置:若使用SpringMVC,可在web.xml中全局配置:

<!-- 仅对POST有效 -->
<filter><filter-name>encodingFilter</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>encodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

局限性:无法解决GET请求的乱码问题(GET参数通过URL传递)。

3. 过滤器(Filter)统一处理

方案一:Spring框架提供的过滤器(推荐)

适用场景:所有请求类型(需额外处理GET)
配置方法:在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配置。

方案二:自定义过滤器(处理GET/POST)

适用场景:需要兼容GET请求且无法修改Tomcat配置时
实现步骤:

编写过滤器类:

public class CustomEncodingFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 设置请求编码request.setCharacterEncoding("UTF-8");// 处理GET请求参数(Tomcat 8+默认UTF-8,低版本需手动解码)if (request instanceof HttpServletRequest) {HttpServletRequest req = (HttpServletRequest) request;if ("GET".equalsIgnoreCase(req.getMethod())) {Map<String, String[]> params = req.getParameterMap();for (Map.Entry<String, String[]> entry : params.entrySet()) {String[] values = entry.getValue();for (int i = 0; i < values.length; i++) {values[i] = new String(values[i].getBytes("ISO-8859-1"), "UTF-8");}}}}// 设置响应编码response.setCharacterEncoding("UTF-8");chain.doFilter(request, response);}
}

配置web.xml:

<filter><filter-name>customEncodingFilter</filter-name><filter-class>com.example.CustomEncodingFilter</filter-class>
</filter>
<filter-mapping><filter-name>customEncodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

优点:全面覆盖GET/POST请求,兼容性更强。

七、自定义类型转换器

1.使用DateTimeFormat注解的方式

JavaBean:

public class User {
@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birthday;}

springmvc.xml:

<mvc:annotation-driven></mvc:annotation-driven>

JSP表单:

<<form action="/user/save2.do" method="post">生日:<input type="text" name="birthday" placeholder="yyyy-MM-dd"/><br/><input type="submit" value="提交" />
</form>

Controller接收:

@RequestMapping("/save2.do")public String save2(User user){System.out.println("user对象:"+user);return "suc";}

2.自定义类型转换器

StringToDate类:

package cn.tx.demo2.Date;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/**** 自定义类型转换器 把String转换成Date*/
public class StringToDate implements Converter<String,Date>{/*** 进行类型转换的方法* @param s     用户输入的内容* @return*/@Overridepublic Date convert(String s) {// 判断if(s == null){throw new RuntimeException("请输入内容");}// 进行转换SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");try {// 进行转换return sdf.parse(s);} catch (ParseException e) {throw new RuntimeException(e);}}}

springmvc.xml:

<!--配置日期类型转换器,类型转换器的组件,把日期类型转换注入到组件对象中--><bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><set><bean class="cn.tx.demo2.Date.StringToDate" /></set></property></bean><!--让映射器、适配器和处理器生效(默认不配置也是可以的)--><mvc:annotation-driven conversion-service="conversionService"/>

八、SpringMVC常用注解详解

1. @RequestParam注解

@RequestParam注解主要用于将请求中的指定名称参数传递给控制器的形参进行赋值。它包含以下属性:

  • value:用于指定请求参数的名称;
  • required:表示请求参数是否为必须提供,默认值为true,若设为false,当请求中无对应参数时不会报错;
  • defaultValue:当请求中未传递该参数时,使用设置的默认值。
package cn.tx.demo3;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;@Controller
@RequestMapping("/dept")
public class DeptController {@RequestMapping("/save1.do")public String save(@RequestParam(value = "username", required = false, defaultValue = "abc") String name) {System.out.println("姓名:" + name);return "suc";}
}

在上述代码中,@RequestParam注解将请求中的username参数赋值给name变量,若请求未携带username参数,name将使用默认值"abc"

2. @RequestBody注解

@RequestBody注解用于获取请求体的内容,需要注意的是,该注解不适用于GET请求。它只有一个required属性,用于表示请求体是否为必须存在,默认值为true

@RequestMapping("/save2.do")
public String save2(@RequestBody String body) {System.out.println("请求体内容:" + body);return "suc";
}

通过@RequestBody,可以方便地获取客户端在请求体中发送的数据,常用于处理JSON、XML等格式的请求数据。

3. @PathVariable注解与Restful风格URL

@PathVariable注解用于绑定URL中的占位符,使URL中的参数能够传递到控制器方法中。其value属性用于指定URL中占位符的名称。

Restful风格的URL具有结构清晰、符合标准、易于理解和扩展方便等优点,它可以根据不同的请求方式(如GETPOSTPUTDELETE等),在相同的请求路径下执行后台不同的方法。

package cn.tx.demo3;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;@Controller
public class EmpController {@RequestMapping(path = "/emp", method = RequestMethod.POST)public String save() {System.out.println("保存员工...");return "suc";}@RequestMapping(path = "/emp", method = RequestMethod.GET)public String findAll() {System.out.println("查询员工...");return "suc";}@RequestMapping(path = "/emp/{id}", method = RequestMethod.GET)public String findById(@PathVariable(value = "id") Integer id) {System.out.println("通过id查询员工..." + id);return "suc";}
}

上述代码中,通过@PathVariable获取URL中的id参数,实现了根据不同的请求方式和参数执行相应业务逻辑。同时,为了更好地支持Restful风格URL,前端控制器的配置需将url-pattern设为/,以便更灵活地处理各类请求。

<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>

4. @RequestHeader注解

@RequestHeader注解用于获取指定请求头的值,通过value属性指定请求头名称。

@RequestMapping("/save3.do")
public String save3(@RequestHeader(value = "Accept") String header) {System.out.println("Accept请求头的值:" + header);return "suc";
}

在实际开发中,该注解可用于获取诸如User - AgentReferer等请求头信息,便于进行请求来源判断、客户端类型识别等操作。

5. @CookieValue注解

@CookieValue注解用于获取指定Cookie名称的值,通过value属性指定Cookie的名称。

@RequestMapping("/save4.do")
public String save4(@CookieValue(value = "JSESSIONID") String cookie) {System.out.println("值:" + cookie);return "suc";
}

利用该注解,可以方便地获取客户端发送的Cookie信息,常用于用户会话管理、身份验证等场景 。


总结

SpringMVC通过清晰的组件分工简化了Web开发,结合参数绑定和视图解析器,能高效处理请求。中文乱码需根据场景选择方案,推荐使用过滤器。对于复杂数据(如Map),只需确保前端参数命名规范即可自动绑定。

http://www.xdnf.cn/news/3966.html

相关文章:

  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】4.3 数据脱敏与安全(模糊处理/掩码技术)
  • 力扣119题解
  • 六、shell脚本--正则表达式:玩转文本匹配的“万能钥匙”
  • Java使用JDBC操作数据库
  • OpenCV进阶操作:图像直方图、直方图均衡化
  • 2.CFD 计算过程概述:Fluent在散热计算中的优势
  • 【Linux】linux入门——基本指令
  • Qt 信号槽机制底层原理学习
  • C++笔记之模板与可变参数模板
  • 动态链接库(DLL)
  • 网狐飞云娱乐三端源码深度实测:组件结构拆解与部署Bug复盘指南(附代码分析)
  • LeetCode 热题 100 17. 电话号码的字母组合
  • 分布式事物
  • VTK 系统架构
  • 【NLP】33. Pinecone + OpenAI :构建自定义语义搜索系统
  • 五一作业-day04
  • 解决跨域的4种方法
  • CRS 16 slot 设备硬件架构
  • 【RK3588嵌入式图形编程】-Cairo-Cairo图形库支持后端
  • 嵌入式Linux驱动学习
  • 哈希算法、搜索算法与二分查找算法在 C# 中的实现与应用
  • 基于机器学习算法预测二手车市场数据清洗与分析平台(源码+定制+讲解) 基于Python的数据挖掘与可视化 二手车数据处理与分析系统开发 (机器学习算法预测)
  • 深入理解 Bash 中的 $‘...‘ 字符串语法糖
  • 浅拷贝和深拷贝的区别
  • Android控件View、ImageView、WebView用法
  • 14.网络钓鱼实战
  • 【论文阅读】DETR+Deformable DETR
  • 【现代深度学习技术】现代循环神经网络07:序列到序列学习(seq2seq)
  • [学成在线]23-面试题总结
  • AIGC学术时代:DeepSeek如何助力实验与数值模拟