springMVC系列(八)——springMVC參數接收詳解
- 2019 年 10 月 30 日
- 筆記
版權聲明:本文為博主原創文章,遵循 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.測試方法
@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(); } }
2.Controller
@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的配置
<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.測試方法
@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
public class TestVo { private String id; private String name; /* getter()、setter()、toString() */ }
3.Controller
@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」
@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接口
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
<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">
4.controller
@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.測試方法
@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
public class ListSon { private List<String> son; /* getter()、setter()、toString() */ }
在controller中用ListSon這個Pojo類作為形參,就可以獲得拿到List參數了
3.controller
@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.測試方法
@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類
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() */ }
3.controller
@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.測試方法
@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
public class Girl { private String id; private String name; private Integer age; /* getter()、setter()、toString() */ }
3.實現轉化接口converter
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
<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>
5.controller
@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.測試方法
@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
@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