版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/luo4105/article/details/72480997
springMVC参数传递有一下几种形式:
1.request、response、session传递。
2.参数绑定
3.url动态参数
这种和servlet是一样的,request.getAttribute(“”),response.setAttribute(“”)等
http的参数是以key-value的形式传递的, springMVC接收参数是通过方法的形参来接收,而不是通过控制器的类成员来接收。
参数绑定分为这么几种形式
1.基本的java对象参数绑定
2.自定义pojo对象参数绑定
3.参数解析绑定pojo
4集合对象参数(List、Set等)绑定
http的参数是以key-value的形式传递的,springMVC会自动绑定key与形参名相同的参数。
@Test
public void strParam() throwsIOException {
InputStream is = HttpUtil.doGet(testUrl + "/string?id=1&name=mark");
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
testUrl是项目的url
public static String testUrl = "http://127.0.0.1:8080/study_ssmvc/params";
HttpUtil.doGet是发送http请求的工具方法,在下面的测试方法中也会出现
public class HttpUtil {
public static InputStream doGet(String urlstr) throws IOException {
URL url= new URL(urlstr);
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
InputStream inputStream= conn.getInputStream();
return inputStream;
}
}
StreamUtils.inputStreamToString是将http响应InputStream转成String便于打印输出的工具方法。在下面的测试方法中也会出现。
public class StreamUtils {
public static String inputStreamToString(InputStreamis, String charset) throws IOException {
byte[] bytes = new byte[1024];
int byteLength = 0;
StringBuffer sb = new StringBuffer();
while((byteLength = is.read(bytes)) != -1) {
sb.append(new String(bytes, 0, byteLength, charset));
}
return sb.toString();
}
}
@ResponseBody
@RequestMapping("string")
public String strParam(String id, String name){
System.out.println("params = id:"+ id + ", name: "+ name);
TestVovo = new TestVo();
vo.setId(id);
vo.setName(name);
return vo.toString();
}
需要注意一点的是”@ResponseBody”的作用是将java对象转成json字符串,以response.write()形式产生响应。需要导入jackson.jar,或者也可以使用fastjson来序列化json。
使用fastjson的配置
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<!-- 配置Fastjson支持 -->
<bean
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json</value>
</list>
</property>
<property name="features">
<list>
<value>WriteMapNullValue</value>
<value>QuoteFieldNames</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
springMVC会自动将http请求参数的key与pojo类中属性名相同的属性绑定。
@Test
public void pojoParam() throwsIOException {
InputStream is = HttpUtil.doGet(testUrl + "/pojo?id=1&name=mark");
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
public class TestVo {
private String id;
private String name;
/*
getter()、setter()、toString()
*/
}
@Test
public void pojoParam() throwsIOException {
InputStream is = HttpUtil.doGet(testUrl + "/pojo?id=1&name=mark");
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
这里把date类型单独拿出来说,http请求的参数是String类型,要把String解析成其他实体类型参数,需要使用自定义类型转化器Converter。
在springMVC中,可以通过Converter对参数进行自定义转化。
date参数类型”yyyy-MM-ddhh:mm:ss”
@Test
public void dateParam() throws IOException {
String date= URLEncoder.encode("2017-5-18 12:12:12");
InputStream is = HttpUtil.doGet(testUrl + "/date?id=1&name=mark&time=" + date);
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
URLEncoder.encode()方法作用是将参数中的空格、特殊字符转成http能传输的格式的字符串。
新建自定义时间转化类CustomDateConverter,实现Converter接口
public class CustomDateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
return sdf.parse(source);
}catch(ParseException e){
e.printStackTrace();
}
return null;
}
}
在springMVC配置文件中注册formattingConversionServiceFactoryBean
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"id="factoryBean" >
<property name="converters"><!-- 在属性converters注册 -->
<list>
<bean class="com.lc.convert.CustomDateConverter"/>
<!-- <bean class="com.lc.convert.GirlConverter" />-->
</list>
</property>
</bean>
<mvc:annotation-driven conversion-service="factoryBean">
也可以注册ConversionServiceFactoryBean,即将formattingConversionServiceFactoryBean 改为ConversionServiceFactoryBean。
ConversionServiceFactoryBean与formattingConversionServiceFactoryBean的区别在于formattingConversionServiceFactoryBean也是继承ConversionService接口,它有两个内建实现类,分别支持数组及数字类型的注解驱动格式化。 如果只用formattingConversionServiceFactoryBean自带的两个内建实现类,在mvc:annotation-driven可以不进行conversion-service的配置,如果有自定义converter,就必须加上mvc:annotation-driven的配置。
<mvc:annotation-driven conversion-service="factoryBean">
@ResponseBody
@RequestMapping("date")
public Map<String, Object> dateParam(TestVo vo, Date time) {
System.out.println("param = "+ vo);
System.out.println("time = "+ time);
Map<String,Object> map= new HashMap<>();
map.put("param",vo);
map.put("time", time);
return map;
}
实际上FormattingConversionServiceFactoryBean类中存在Date转化类,不需要我们再去写,我们只需要使用” @DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss") Date time”放在参数前就可以了。
FormattingConversionServiceFactoryBean不仅支持@ DateTimeFormat,而且支持@NumberFormat标签,可对数字类型属性标注。
@Test
public voidlistParam() throwsIOException {
String date= URLEncoder.encode("2017-5-18 12:12:12");
InputStream is = HttpUtil.doGet(testUrl + "/list?id=1&name=mark&time=" + date+ "&son=Bob&son=John");
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
Controller的形参是不支持直接用List<String>son,去接收List,它会抛出异常:
org.springframework.beans.BeanInstantiationException:Failed to instantiate [java.util.List]: Specified class is an interface
这里需要把List<String> son用一个pojo去包装一下,
public class ListSon {
private List<String> son;
/*
getter()、setter()、toString()
*/
}
在controller中用ListSon这个Pojo类作为形参,就可以获得拿到List参数了
@ResponseBody
@RequestMapping("list")
public Map<String, Object> listParam(TestVo vo, ListSon son) {
System.out.println("param = "+ vo);
System.out.println("son = "+ son.toString());
Map<String,Object> map= new HashMap<>();
map.put("param",vo);
map.put("son", son);
return map;
}
Set、Map相似
对于List<pojo>,自定义pojo类这种接收参数形式,有两种方式去接收
1.前台转成json,以json字符串的形式请求服务端,服务器解析json,转成List<pojo>,这里不介绍这一种。
2.http请求直接放数组,controller直接以包装List<pojo>去接收
先看测试方法,注意请求参数格式
@Test
public void pojolistParam() throwsIOException {
String date = URLEncoder.encode("2017-5-18 12:12:12");
InputStream is = HttpUtil.doGet(testUrl + "/pojolist?vos[0].id=1&vos[1].id=2&vos[0].name=john&vos[1].name=mark&time=" + date+ "&son=Bob&son=John");
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
参数的形式是” vos[0].id=1&vos[1].id=2&vos[0].name=john&vos[1].name=mark”这样的形式
public class ListSon {
private List<String> son;
private List<TestVo> vos;
/*
getter()、setter()、toString()
*/
}
TestVo
public class TestVo {
private String id;
private String name;
/*
getter()、setter()、toString()
*/
}
@ResponseBody
@RequestMapping("pojolist")
public Map<String, Object> listParam( ListSon son) {
System.out.println("son = "+ son.toString());
Map<String,Object> map= new HashMap<>();
map.put("son", son);
return map;
}
这实际上类似于Date的参数解析绑定
需求:girl类有id、name、age三个属性,参数上传格式”girl=id|name|age”的形式,如”girl=1|jonny|18”,实现springMVC形参直接用Girl对象接收” id|name|age”字符串并解析。
@Test
public void customParam() throws IOException {
String date= URLEncoder.encode("2017-5-18 12:12:12");
InputStream is = HttpUtil.doGet(testUrl + "/cutom?id=1&name=mark&time=" + date+ "&son=Bob&son=John&girl=Tim|Andy|Juddy");
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
关注最后一个参数girl的形式
public class Girl {
private String id;
private String name;
private Integer age;
/*
getter()、setter()、toString()
*/
}
public class GirlConverter implements Converter<String, Girl> {
@Override
public Girl convert(String source) {
String[]girls= source.split("\\|");
Girl girl= new Girl();
girl.setId(girls[0]);
girl.setName(girls[1]);
girl.setAge(Integer.valueOf(girls[2]));
return girl;
}
}
这只是简单大致的实现一下,正常的情况应加上异常处理,这里这么写,便于理解。注意情况见上面的Date类型数据绑定
在springMVC配置文件中注册formattingConversionServiceFactoryBean
<mvc:annotation-driven conversion-service="factoryBean">
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="factoryBean">
<property name="converters"><!-- 在属性converters注册 -->
<list>
<bean class="com.lc.convert.GirlConverter"/>
</list>
</property>
</bean>
@ResponseBody
@RequestMapping("custom")
public Map<String, Object> customParam(TestVo vo, List<String> son, Girl girl) {
System.out.println("param = "+ vo);
System.out.println("son = "+ son.toString());
System.out.println("girl = "+ girl.toString());
Map<String,Object> map= new HashMap<>();
map.put("param",vo);
map.put("son", son);
map.put("girl", girl);
return map;
}
在restful风格的接口中,会以url的形式传参,SpringMVC支持获得url的动态参数
@Test
public void urlParam() throws IOException {
InputStream is = HttpUtil.doGet(testUrl + "/url/mark");
String response= StreamUtils.inputStreamToString(is, "UTF-8");
System.out.println(response);
}
url后的mark就是参数
@ResponseBody
@RequestMapping("/url/{name}")
public Map<String, Object> customParam(@PathVariable("name") String name) {
System.out.println("name = "+ name);
Map<String,Object> map= new HashMap<>();
map.put("name", name);
return map;
}