springMvc如何接受多個物件引數
阿新 • • 發佈:2020-08-03
在程式碼開發過程中,引數的定義非常重要,目前springmvc提供的較多的引數獲取方式,譬如 @PathVariable 和@RequestParam,
或者通過增加如下註解
<mvc:annotation-driven> </mvc:annotation-driven>
mvc:annotation-driven預設增加了MappingJackson2HttpMessageConverter,可以將傳遞進來的body體解析成對應的JAVA物件。
但是存入如下問題
1、@PathVariable 和@RequestParam只能解析基礎的Java格式,int string boolean等,2、MappingJackson2HttpMessageConverter只能將物件轉變為一個JAVA Bean,
如果我們有兩個java bean 定義如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Student {
private String name;
private int year;
public String getName() {
return name;
}
public void setName(String name) {
this .name = name;
}
public int getYear() {
return year;
}
public void setYear( int year) {
this .year = year;
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Info {
private String city;
private String address;
public String getCity() {
return city;
}
public void setCity(String city) {
this .city = city;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this .address = address;
}
}
|
如果我們定義了一個介面,需要傳遞這兩個物件資訊,採用MappingJackson2HttpMessageConverter就會比較麻煩。
這裡講解一個如何實現同時傳遞多個物件的方法,我們最終定義的介面如下
public Student addstudentpost(@JsonObject Student student,@JsonObject Info info)
原理是實現我們自定義的HandlerMethodArgumentResolver,並且插入到springMvc的引數解析佇列中。
1、首先定義一個註解類
1 2 3 4 5 |
@Target (ElementType.PARAMETER)
@Retention (RetentionPolicy.RUNTIME)
@Documented
public @interface JsonObject {
}
|
2、其次實現自定義的引數解析類JsonObjectArgResolverHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
public class JsonObjectArgResolverHandler implements HandlerMethodArgumentResolver {
@Override public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(JsonObject. class );
}
@Override public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
try {
JSONObject para = getRequestInfo(nativeWebRequest);
Class<?> type = methodParameter.getParameterType();
String name = methodParameter.getParameterName();
if ( null != para && para.containsKey(name)) {
return JSON.parseObject(para.getString(name), type);
}
} catch (Exception e) {
}
return null ;
}
private JSONObject getRequestInfo(NativeWebRequest webRequest) throws IOException {
JSONObject para = new JSONObject();
HttpServletRequest httpServletRequest =
(HttpServletRequest) webRequest.getNativeRequest(HttpServletRequest. class );
String method = httpServletRequest.getMethod();
if (!method.equals( "GET" ) && !method.equals( "DELETE" )) {
if ( null != httpServletRequest.getAttribute( "para" )) {
try {
para = JSON.parseObject(httpServletRequest.getAttribute( "para" ).toString());
} catch (Exception e) {
}
} else {
StringBuilder buffer = new StringBuilder();
BufferedReader reader = httpServletRequest.getReader();
String line;
while ((line = reader.readLine()) != null ) {
buffer.append(line);
}
httpServletRequest.setAttribute( "para" , buffer.toString());
try {
para = JSON.parseObject(buffer.toString());
} catch (Exception e) {
}
}
} else {
Map<String, String[]> parameterMap = webRequest.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
String key = entry.getKey();
String values = StringUtils.join(entry.getValue());
para.put(key, values);
}
}
return para;
}
}
|
注意:
a、supportsParameter表明我們的類只支援解析帶有JsonObject的物件解析。
b、httpServletRequest的body體只能讀取一次,再次讀取後就返回空,因為帶有JsonObject註解的物件都會執行一遍,在第一次獲取後需要將body體儲存下來,以便下次使用。所有有如下的程式碼
將body體儲存
1 |
httpServletRequest.setAttribute( "para" , buffer.toString());
|
讀取Attribute,沒有則從body體讀取。
1 if (null != httpServletRequest.getAttribute("para")) { 2 try { 3 para = JSON.parseObject(httpServletRequest.getAttribute("para").toString()); 4 } catch (Exception e) { 5 } 6 } else {
3、將JsonObjectArgResolverHandler配置進xml檔案中。
<mvc:annotation-driven> <mvc:argument-resolvers> <bean class="com.nuaa.handler.JsonObjectArgResolverHandler"></bean> </mvc:argument-resolvers> <mvc:return-value-handlers> <bean class="com.nuaa.handler.ReponseJsonBodyMethodReturnValueHandler"> <property name="messageConverters"> <list> <bean class="com.nuaa.handler.Base64JsonHttpMessageConverter"/> </list> </property> </bean> </mvc:return-value-handlers> </mvc:annotation-driven>
這個我們可以定義如下的介面,
@RequestMapping(value="/addstudentpost", method = RequestMethod.POST,produces="application/json")
@ResponseJsonBody
public Student addstudentpost(@JsonObject Student student,@JsonObject Info info){
student.setName(JSON.toJSONString(student)+JSON.toJSONString(info)+(new Date()));
return student;
}
整個函式的定義就比較明瞭和直觀。
關於ResponseJsonBody的註解,請檢視http://www.cnblogs.com/wangjiuyong/articles/7162207.html
在readme中有測試方法:
http://localhost:8080/spring/controlhandler/addstudentget?student={"name":"zhang","year":100}&info={"address":"yuhuataiqu","city":"nanjing"} http://localhost:8080/spring/controlhandler/addstudentpost { "student": { "name": "wangjiuyong", "year": 2000 }, "info": { "address": "yuhuataiqu", "city": "nanjing" } }https://www.cnblogs.com/wangjiuyong/articles/7182650.html