1. 程式人生 > 實用技巧 >springMvc如何接受多個物件引數

springMvc如何接受多個物件引數

在程式碼開發過程中,引數的定義非常重要,目前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 publicclassStudent { privateString name; privateintyear; publicString getName() { returnname; } publicvoidsetName(String name) { this.name = name; } publicintgetYear() { return
year; } publicvoidsetYear(intyear) { this.year = year; } }

  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 publicclassInfo { privateString city; privateString address; publicString getCity() { returncity; } publicvoidsetCity(String city) { this.city = city; } publicString getAddress() {
returnaddress; } publicvoidsetAddress(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@interfaceJsonObject { }

 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 publicclassJsonObjectArgResolverHandlerimplementsHandlerMethodArgumentResolver { @OverridepublicbooleansupportsParameter(MethodParameter methodParameter) { returnmethodParameter.hasParameterAnnotation(JsonObject.class); } @OverridepublicObject resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory)throwsException { try{ JSONObject para = getRequestInfo(nativeWebRequest); Class<?> type = methodParameter.getParameterType(); String name = methodParameter.getParameterName(); if(null!= para && para.containsKey(name)) { returnJSON.parseObject(para.getString(name), type); } }catch(Exception e) { } returnnull; } privateJSONObject getRequestInfo(NativeWebRequest webRequest)throwsIOException { JSONObject para =newJSONObject(); 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 =newStringBuilder(); 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); } } returnpara; } }

  注意:

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