在restful風格的api中,put/patch方法一般用於更新數據。在項目的代碼中,使用的是httpclient 4.5,是這樣寫的:

protected jsonobject dohttpurirequest(httpurirequest httpurirequest) {

jsonobject result = null;

httpclient httpclient = httpclients.createdefault();

try {

httpresponse httpresponse = httpclient.execute(httpurirequest);

statusline responsestatusline = httpresponse.getstatusline();

int statuscode = responsestatusline.getstatuscode();

if (statuscode == 200) {

httpentity responseentity = httpresponse.getentity();

string jsonstring = entityutils.tostring(responseentity, character_set);

result = new jsonobject(jsonstring);

entityutils.consume(responseentity);

} else {

// error handling

}

} catch (ioexception e) {

e.printstacktrace();

return onlocalerror(e);

}

return result;

}

protected jsonobject dohttppatch(string uri, map params) {

jsonobject result = null;

httppatch httppatch = new httppatch(uri);

list nvps = constructnvps(params); // constructing name-value pair

try {

httppatch.setentity(new urlencodedformentity(nvps, character_set));

result = dohttpurirequest(httppatch);

} catch (unsupportedencodingexception e) {

e.printstacktrace();

return onlocalerror(e);

}

return result;

}


其中dohttpurirequest()是一個處理髮送請求的工具函數,dohttppatch()是具體處理數據的函數。
可見寫法和一個普通的post請求差不多,只是將httppost換成httppatch。
可是在server端,比如在params中有一個參數叫key,值是value,在controller裏面,能識別到這是一個patch方法,可是key的值是null。就是servlet不能從form裏面獲取參數。
google查了一下原因,大體是説patch這個方法很新,就算到tomcat 7.0.39也都不支持。那怎麼破呢?有兩個辦法:

  1. 用uri來請求 既然不能使用form來獲取參數,那就寫在uri的尾巴吧:
protected jsonobject dohttppatchwithuri(string uri, map params) {

jsonobject result = null;

uribuilder uribuilder = new uribuilder();

uribuilder.setpath(uri);

uribuilder.setparameters(constructnvps(params));

try {

uri builturi = uribuilder.build();

httppatch httppatch = new httppatch(builturi);

result = dohttpurirequest(httppatch);

} catch (urisyntaxexception e) {

e.printstacktrace();

return onlocalerror(e);

}

return result;

}

  1. 使用了這種做法,servlet可以獲得參數了。
    這個方法有一個問題。就是即使key是null值,在uri的參數也會帶上。在servlet裏面接收,key的值會變成”“(空字符串)。這樣在restful風格api裏面會有歧義:究竟是不更新,還是更新成空字符串呢?
  2. 在web.xml中加入一個filter
    另一種做法是保持使用上面post風格的方法,在web.xml中加入一個filter:
    httpputformcontentfilter
    org.springframework.web.filter.httpputformcontentfilter
    httpputformcontentfilter
    springwebmvcdispatcher
    其中springwebmvcdispatcher是servlet的名字。
    filter的工作是從request body的form data裏面讀取數據,然後包裝成一個servletrequest,使得servletrequest.getparameter*()之類的方法可以讀取到數據。