前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >springMVC系列(八)——springMVC参数接收详解

springMVC系列(八)——springMVC参数接收详解

作者头像
逝兮诚
发布2019-10-30 13:18:04
1.3K0
发布2019-10-30 13:18:04
举报
文章被收录于专栏:代码人生代码人生

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/luo4105/article/details/72480997

参数接收

springMVC参数传递有一下几种形式:

1.request、response、session传递。

2.参数绑定

3.url动态参数

request、response、session传递

这种和servlet是一样的,request.getAttribute(“”),response.setAttribute(“”)等

参数绑定

http的参数是以key-value的形式传递的, springMVC接收参数是通过方法的形参来接收,而不是通过控制器的类成员来接收。

参数绑定分为这么几种形式

1.基本的java对象参数绑定

2.自定义pojo对象参数绑定

3.参数解析绑定pojo

4集合对象参数(List、Set等)绑定

基本的java对象参数绑定

http的参数是以key-value的形式传递的,springMVC会自动绑定key与形参名相同的参数。

1.测试方法
代码语言:javascript
复制
@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

代码语言:javascript
复制
public static String testUrl = "http://127.0.0.1:8080/study_ssmvc/params";

HttpUtil.doGet是发送http请求的工具方法,在下面的测试方法中也会出现

代码语言:javascript
复制
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便于打印输出的工具方法。在下面的测试方法中也会出现。

代码语言:javascript
复制
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();
    }
}
2.Controller
代码语言:javascript
复制
@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();
}
3.测试通过、响应数据

需要注意一点的是”@ResponseBody”的作用是将java对象转成json字符串,以response.write()形式产生响应。需要导入jackson.jar,或者也可以使用fastjson来序列化json。

使用fastjson的配置

代码语言:javascript
复制
<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>

Pojo数据绑定

springMVC会自动将http请求参数的key与pojo类中属性名相同的属性绑定。

1.测试方法
代码语言:javascript
复制
@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);
}
2.Pojo
代码语言:javascript
复制
public class TestVo {
   
    private String id;
    private String name;
    /*
     getter()、setter()、toString()
    */
}
3.Controller
代码语言:javascript
复制
@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);
}
4.测试通过、响应数据

Date类型数据解析绑定

这里把date类型单独拿出来说,http请求的参数是String类型,要把String解析成其他实体类型参数,需要使用自定义类型转化器Converter。

在springMVC中,可以通过Converter对参数进行自定义转化。

1.测试方法

date参数类型”yyyy-MM-ddhh:mm:ss”

代码语言:javascript
复制
@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能传输的格式的字符串。

2.实现转化接口converter

新建自定义时间转化类CustomDateConverter,实现Converter接口

代码语言:javascript
复制
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;
    }
}
3.配置转化类

在springMVC配置文件中注册formattingConversionServiceFactoryBean

代码语言:javascript
复制
<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的配置。

代码语言:javascript
复制
<mvc:annotation-driven conversion-service="factoryBean">
4.controller
代码语言:javascript
复制
@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;
}
5.测试通过、响应数据
使用@ DateTimeFormat

实际上FormattingConversionServiceFactoryBean类中存在Date转化类,不需要我们再去写,我们只需要使用” @DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss") Date time”放在参数前就可以了。

FormattingConversionServiceFactoryBean不仅支持@ DateTimeFormat,而且支持@NumberFormat标签,可对数字类型属性标注。

简单List集合参数

1.测试方法
代码语言:javascript
复制
@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去包装一下,

2.Pojo
代码语言:javascript
复制
public class ListSon {
   
    private List<String> son;
         /*
     getter()、setter()、toString()
    */
}

在controller中用ListSon这个Pojo类作为形参,就可以获得拿到List参数了

3.controller
代码语言:javascript
复制
@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;
}
4.测试通过、响应数据

Set、Map相似

复杂的List集合

对于List<pojo>,自定义pojo类这种接收参数形式,有两种方式去接收

1.前台转成json,以json字符串的形式请求服务端,服务器解析json,转成List<pojo>,这里不介绍这一种。

2.http请求直接放数组,controller直接以包装List<pojo>去接收

先看测试方法,注意请求参数格式

1.测试方法
代码语言:javascript
复制
@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”这样的形式

2.pojo类
代码语言:javascript
复制
public class ListSon {
   
    private List<String> son;
    private List<TestVo> vos;
         /*
     getter()、setter()、toString()
    */
}

TestVo

代码语言:javascript
复制
public class TestVo {
   
    private String id;
    private String name;
    /*
     getter()、setter()、toString()
    */
}
3.controller
代码语言:javascript
复制
@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;
}
4.测试通过、响应数据

自定义参数解析pojo

这实际上类似于Date的参数解析绑定

需求:girl类有id、name、age三个属性,参数上传格式”girl=id|name|age”的形式,如”girl=1|jonny|18”,实现springMVC形参直接用Girl对象接收” id|name|age”字符串并解析。

1.测试方法
代码语言:javascript
复制
@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的形式

2.Pojo
代码语言:javascript
复制
public class Girl {
   
    private String id;
    private String name;
    private Integer age;
/*
     getter()、setter()、toString()
    */
}
3.实现转化接口converter
代码语言:javascript
复制
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类型数据绑定

4.配置转化类

在springMVC配置文件中注册formattingConversionServiceFactoryBean

代码语言:javascript
复制
<mvc:annotation-driven conversion-service="factoryBean">
代码语言:javascript
复制
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="factoryBean">
   <property name="converters"><!-- 在属性converters注册 -->
        <list>
            <bean class="com.lc.convert.GirlConverter"/>
        </list>
   </property>
</bean>
5.controller
代码语言:javascript
复制
@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;
}
6.测试通过、响应数据

URL动态参数绑定

在restful风格的接口中,会以url的形式传参,SpringMVC支持获得url的动态参数

1.测试方法

代码语言:javascript
复制
@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就是参数

2.controller

代码语言:javascript
复制
@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;
}

3.测试通过、响应数据

代码地址:https://code.csdn.net/luo4105/study_ssmvc/tree/master

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-05-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参数接收
    • request、response、session传递
      • 参数绑定
        • 基本的java对象参数绑定
        • Pojo数据绑定
        • Date类型数据解析绑定
        • 简单List集合参数
        • 复杂的List集合
        • 自定义参数解析pojo
      • URL动态参数绑定
        • 1.测试方法
        • 2.controller
        • 3.测试通过、响应数据
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档