Spring MVC之请求参数绑定
一、请求参数的绑定
服务器端要获得请求的参数,需要进行数据的封装,SpringMVC可以接收如下类型的参数。
Controller中的方法的参数名称要与请求参数的name一致,参数值会自动映射匹配,并且能自动做类型转换;自动的类型转换是指从String向其他类型的转换。
数据类型 | 描述 | 要求 |
---|---|---|
基本类型参数 | 包括基本类型和 String 类型 | 参数名称必须和控制器中方法的形参名称保持一致,严格区分大小写 |
POJO 类型参数 | 包括实体类,以及关联的实体类 | 要求表单中参数名称和 POJO 类的属性名称保持一致。并且控制器方法的参数类型是 POJO 类型。 |
数组和集合类型参数 | 包括 List 结构和 Map 结构的集合(包括数组) | 1:要求集合类型的请求参数必须在 POJO 中。2:在表单中请求参数名称要和 POJO 中集合属性名称相同。 3.给 List 集合中的元素赋值,使用下标,给 Map 集合中的元素赋值,使用键值对。4:接收的请求参数是 json 格式数据时,需要借助@RequestBody 注解实现。 |
1.基本类型和String类型
1.简单数据类型:值必须存在,不传可以通过默认值代替
2.包装类型:值可以为空
http://localhost:8080/test?username=admin&password=123
@RequestMapping("/test")
public String testParam(String username,String password,
@RequestParam(defaultValue="0",name="flag" int flag,
Integer age,){
System.out.println("用户名:"+ username);
System.out.println("密码:"+ password);
System.out.println("请求来源:"+ flag);
System.out.println("年龄:"+ age);
return "success";
}
2.POJO(VO)类型
public class User implements Serializable {
private Integer id;
private String name;
private Integer age;
private Car car;
//getters and setters
}
public class Car implements Serializable {
private Integer id;
private String brand;
private Float price;
//getters and setters
}
<form action="test" method="post">
姓名:<input type="text" name="name" /><br/>
年龄:<input type="text" name="age" /><br/>
车辆品牌:<input type="text" name="car.brand" /><br/>
车辆价格:<input type="text" name="car.price" /><br/>
<input type="submit" value="提交" />
</form>
@RequestMapping("/test")
public String testParam(User user){
System.out.println("User :"+user);
return "success";
}
3.POJO(VO)类中包含List、Map、Set集合类型
Map最为灵活,它需要绑定在对象上,Set和List类似,也需要绑定在对象上,而不能直接写在Controller方法的参数中。
public class User implements Serializable {
private Integer id;
private String name;
private Integer age;
private List<Car> list;
private Map<String,Car> map;
private Set<Car> set;
//getters and setters
}
public class Car implements Serializable {
private Integer id;
private String brand;
private Float price;
//getters and setters
}
<form action="test" method="post">
姓名:<input type="text" name="name" /><br/>
年龄:<input type="text" name="age" /><br/>
车辆品牌:<input type="text" name="list[0].brand" /><br/>
车辆价格:<input type="text" name="list[0].price" /><br/>
车辆品牌:<input type="text" name="map['one'].brand" /><br/>
车辆价格:<input type="text" name="map['one'].price" /><br/>
车辆品牌1:<input type="text" name="set[0].brand" value="BM"/><br/>
车辆品牌2:<input type="text" name="set[1].brand" value="BC"/><br/>
<input type="submit" value="提交" />
</form>
/**
* POJO类中包含集合类型参数
* @return
*/
@RequestMapping("/test")
public String testParam(User user){
System.out.println("User :"+user);
return "success";
}
当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装
var userList = new Array();
userList.push({name:"zhangsan",age:18});
userList.push({name:"lisi",age:28});
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/test",
data:JSON.stringify(userList),
contentType:"application/json;charset=utf-8"
});
@RequestMapping(value="/test")
@ResponseBody
public void save15(@RequestBody List<User> userList) {
System.out.println(userList);
}
4.数组类型
@RequestMapping("/test")
public String testParam(String[] strs,@RequestParam(value="ids")String[] ids){
System.out.println("strs:"+strs);
System.out.println("ids:"+ids);
return "success";
}
5.使用 ServletAPI 对象作为方法参数
SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。
支持原始 ServletAPI 对象有:
HttpServletRequest、HttpServletResponse、HttpSession、java.security.Principal、Locale、InputStream、OutputStream、Reader、Writer
/**
* 使用 ServletAPI 对象作为方法参数
* @return
*/
@RequestMapping("/test")
public String testParam(HttpServletRequest request, HttpServletResponse response, HttpSession session){
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "success";
}
二、开启静态资源的访问
当有静态资源需要加载时,比如
js/css/images
等文件,通过控制台开发者工具抓包发现,没有加载到js/css/images
等文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,可以通过以下两种方式指定放行静态资源:
<!--第一种-->
<!-- location 表示路径,mapping 表示文件,**表示该目录下的文件以及子目录的文件 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/scripts/" mapping="/javascript/**"/>
<!--第二种-->
<mvc:default-servlet-handler/>
三、配置全局乱码过滤器
post方式
在 web.xml 中配置一个过滤器
<!--配置全局过滤的filter-->
<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>
get方式
tomacat 对 GET和 POST 请求处理方式是不同的,GET请求的编码问题,要改 tomcat 的 server.xml配置文件
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"/>
改为:
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"
useBodyEncodingForURI="true"/>
当遇到 ajax 请求仍然乱码时,使用如下配置:
useBodyEncodingForURI="true"改为 URIEncoding="UTF-8"
四、自定义类型转换器
表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明Spring框架内部会默认进行数据类型转换。如果想自定义数据类型转换,可以实现Converter的接口。
在特殊情况下就需要自定义类型转换,如日期类型的转换。
例如:参数date=2020-01-01,springmvc使用String类型接收能够正常转换处理。但当使用Date 类型接收时将会报错。
@RequestMapping("/test")
public String testParam( String date){
System.out.println("date:"+date);
return "success";
}
@RequestMapping("/test")
public String testParam( Date date){
System.out.println("date:"+date);
return "success";
}
1.自定义类型转换器
定义一个类,实现 Converter 接口,该接口有两个泛型,S:表示接受的类型,T:表示目标类型。
/**
* A converter converts a source object of type {@code S} to a target of type {@code T}.
*
* <p>Implementations of this interface are thread-safe and can be shared.
*
* <p>Implementations may additionally implement {@link ConditionalConverter}.
*
* @author Keith Donald
* @since 3.0
* @param <S> the source type
* @param <T> the target type
*/
@FunctionalInterface
public interface Converter<S, T> {
/**
* Convert the source object of type {@code S} to target type {@code T}.
* @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
* @return the converted object, which must be an instance of {@code T} (potentially {@code null})
* @throws IllegalArgumentException if the source cannot be converted to the desired target type
*/
@Nullable
T convert(S source);
}
/**
* 把字符串转换日期
*/
public class StringToDateConverter implements Converter<String,Date>{
/**
* String source 传入字符串
* @param source
* @return
*/
@Override
public Date convert(String source) {
if(source == null){
throw new RuntimeException("参数不能为空!");
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
// 把字符串转换日期
return df.parse(source);
} catch (Exception e) {
throw new RuntimeException("字符串转日期类型转换出错!");
}
}
}
2.注册自定义类型转换器
在 spring 配置文件中配置类型转换器,spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去。
<!--配置自定义类型转换器-->
<!-- 配置类型转换器工厂 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 给工厂注入一个新的类型转换器 -->
<property name="converters">
<set>
<bean class="cn.ybzy.util.StringToDateConverter"/>
</set>
</property>
</bean>
3.引用配置的类型转换服务
在 annotation-driven 标签中引用配置的类型转换服务
<!-- 引用自定义类型转换器 -->
<mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven>
配置完成后,查询Converter接口的实现,发现自定义类型转换已经注册到转换服务中.
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137121.html