一、使用Servlet原生对象获取参数
SpringMVC也支持使用Servlet原生对象,在方法参数中定义HttpServletRequest 、HttpServletResponse 、 HttpSession 等类型的参数即可直接在方法中使用。
1.1 控制器方法
代码语言:javascript复制// 使用Servlet原生对象
@RequestMapping("c1/param8")
public void servletParam(HttpSession session,HttpServletRequest request, HttpServletResponse response){
// 原生对象获取参数
System.out.println(request.getParameter("name"));
System.out.println(response.getCharacterEncoding());
System.out.println(session.getId());
}
这个就是一个很经典的利用request内置对象获取参数了。请求之后在控制台打印参数和编码方式还有对应的sessionId。 访问路径:http://localhost:8080/c1/param8?name=LYL
1.2 测试结果
OK,可以看得出来是已经成功把参数值和编码方式和sessionId给查询出来了 一般情况下,在SpringMVC中都有对Servlet原生对象的方法的替代,推荐使SpringMVC的方式代替Servlet原生对象。
二、自定义参数类型转换器
前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器将字符串参数转为需要的类型。如:
代码语言:javascript复制// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){
System.out.println(username " " age);
}
但在某些情况下,无法将字符串转为需要的类型,如:
// 自定义转换日期格式字符串
@RequestMapping("c1/param9")
public void dataParam(Date birthday){
System.out.println(birthday);
}
此时我们测试一下看看是什么结果:
控制台输出:
报错原因:
[WARNING]Resolved[org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2025-01-01'; nested exception is java.lang.IllegalArgumentException] 具体意思就是:[org.springframework.web.method.annotation.MethodArgumentTypeMismatchException:未能将类型为“java.lang.String”的值转换为所需类型“java.util.Date”;嵌套异常为org.springfframework.core.covert.ConversionFailedException:无法将值“2025-01-01”从类型[java.lang.SString]转换为类型[java.util.Date];嵌套异常为java.lang.IllegalArgumentException]
2.1 编写类型转换器类
代码语言:javascript复制由于日期数据有很多种格式,SpringMVC没办法把所有格式的字符串转换成日期类型。比如参数格式为 birthday=2025-01-01 时,SpringMVC就无法解析参数。此时需要自定义参数类型转换器。 首先得定义类型转换器类,实现Converter接口。写法如下:
package com.example.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DataConverter implements Converter<String, Date> {
/**
* 转换方法
* @param s 转换前的数据
* @return 转换后的数据
*/
@Override
public Date convert(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
Date date = null;
try{
date = sdf.parse(s);
} catch (ParseException e) {
System.out.println("转换成日期格式出错了!");
e.printStackTrace();
}
return date;
}
}
2.2 注册类型转换器对象
代码语言:javascript复制<!-- 配置转换器工厂 -->
<bean id="dateConverter" class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 转换器集合 -->
<property name="converters">
<set>
<!-- 自定义转换器 -->
<bean class="com.example.converter.DataConverter"></bean>
</set>
</property>
</bean>
<!-- 使用转换器工厂 -->
<mvc:annotation-driven conversion-service="dateConverter"></mvc:annotation-driven>
OK,加了上面这些我们再运行测试一遍看看控制能否成功接收
2.3 测试结果
可以看到报的是404错误,没有找到这个页面,而不是400了
OK,控制台也成功打印出来了。
三、编码过滤器
在传递参数时,tomcat8以上能处理get请求的中文乱码,但不能处理post请求的中文乱码
3.1 JSP表单
代码语言:javascript复制<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>专属页面</title>
</head>
<body>
<form action="/c1/param3" method="post">
<table>
<tr>
<th>id:</th>
<td><input name="id"/></td>
</tr>
<tr>
<th>姓名:</th>
<td><input name="name"/></td>
</tr>
<tr>
<th>性别:</th>
<td><input name="sex"/></td>
</tr>
<tr>
<th>住址:</th>
<td><input name="address.info"/></td>
</tr>
<tr>
<th>邮编:</th>
<td><input name="address.postcode"/></td>
</tr>
<tr align="center">
<td><input type="submit"/></td>
</tr>
</table>
</form>
</body>
</html>
这里是一个表单提交的页面
3.2 控制器方法
代码语言:javascript复制控制器方法我就沿用了之前的,如下:
@RequestMapping("c1/param3")
public void objParam2(Student student){
System.out.println(student);
}
3.3 配置过滤器
代码语言:javascript复制SpringMVC提供了处理中文乱码的过滤器,在web.xml中配置该过滤器即可解决中文乱码问题:添加如下配置:
<!-- SpringMVC中提供的字符编码过滤器,放在所有过滤器的最上方 -->
<filter>
<filter-name>encFilter</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>encFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.4 测试结果
提交上述信息,看看控制台打印有没有乱码,如果没有乱码,则说明字符编码过滤器配置成功。
OK,说明确实是可以了,并且表单提交的name属性和Student属性对应的话,也是可以直接赋值给对应的参数的。
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!