前言:
springmvc對注解的支持非常靈活和飄逸, 也得web編程少了以往很大一坨配置項. 另一方面移動互聯網的到來, 使得REST API變得流行, 甚至成為主流. 因此我們來關注下springmvc對rest api的支持程度, 以及需要做的工作評估.
樣例設計和准備:
springmvc學習筆記系列的文章目錄:
• idea創建springmvc項目
REST API的設計原則遵循之前的博文來實現
• 移動互聯網實戰--Web Restful API設計和基礎架構
初步設計一個查詢系統, 通過userid, 返回該用戶的詳細信息.
請求url:
http://{host}:{port}/rest/demo/query_user_by_id?user_id={user_id}
響應結果:
{
success:true,
errCode:0,
errMsg:"OK",
value:{
username:"lilei",
userId:"1001",
age:18
}
}
樣例中, 請求參數扁平化(HTTP request params), 結果采用JSON來組織.
編程:
按之前博文"idea創建springmvc項目"創建springmvc項目.
先在mvc-dispatcher-servlet.xml中, 添加如下項
<context:annotation-config> <mvc:annotation-driven />
注: 支持各類注解類, 如ResponseBody, RequestBody, JSON/XMl轉化.
添加實體類TResult和UserInfo類.
TResult類設計如下:
public class TResult<T> {
private boolean success = false;
private int errCode = 0;
private String errMsg = "OK";
private T value = null;
}
注: 這邊省略了各個屬性成員的getter和setter, 需要補上.
UserInfo類的定義如下:
public class UserInfo {
private String userId;
private String username;
private int age;
}
注: 這邊省略了各個屬性成員的getter和setter, 需要補上.
編寫自定義的Controller類RestController.
@Controller
@RequestMapping(value = "/rest/demo")
public class RestController {
@RequestMapping(value="/query_user_by_id", method=RequestMethod.GET)
public @ResponseBody TResult<UserInfo> queryUserById(@RequestParam(value="user_id") String userId) {
TResult<UserInfo> result = new TResult<UserInfo>();
UserInfo userInfo = new UserInfo();
userInfo.setUserId(userId);
userInfo.setUsername("李雷");
userInfo.setAge(18);
result.setValue(userInfo);
result.setSuccess(true);
return result;
}
}
定義了queryUesrById的方法, 返回實體TResult<UserInfo>, 指定注解@ResponseBody, SpringMVC會幫助將其默認轉化為JSON格式.
測試和迭代:
在瀏覽器中, 輸入http://127.0.0.1:8080/rest/demo/query_user_by_id?user_id=1001, 結果如下所示:

出現了http status 406(Not Acceptable)的錯誤.
網上搜了一圈后, 嘗試各種靈丹妙葯后, 大多不靈光. 究其原因, springmvc的版本不一致.
由於我的springmvc為4.1.1, 則依照博文"Spring WebMVC 4.1返回json時導致的 406(Not Acceptable)問題"的說法, 添加fasterxml的jackson包即可解決.
在pom.xml中, 添加如下依賴項:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.5.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.5.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.1</version> </dependency>
重新部署, 再次測試, 這次正常了.

該案例就正式通過了, 值得慶幸.
問題匯總:
web開發中, 最讓人頭痛的就是中文亂碼問題了, 所幸這次沒有碰到. 不過居安思危, 防范於未然. 這邊也總結下.
若返回的JSON字符串中有中文亂碼, 可以在@RequestMapping中, 添加項 produces = "application/json;charset=UTF-8", 構成如下形式:
@RequestMapping(value="/query_user_by_id", method=RequestMethod.GET, produces = "application/json;charset=UTF-8")
當然也可能是字符編碼本身非UTF-8導致, 比如編輯器的文字編碼為GBK時, 你按UTF-8返回, 就有可能亂碼.
這可以通過神器idea的右下角編碼類型來修改.

對於JAVA實體類轉化為JSON格式, 需要該JAVA的POJO類, 需要完備該類的getter/setter方法. 避免莫名其妙的情況.
總結:
springmvc編寫REST API確實方便, 特別是注解類的大量使用, 使得配置精簡, 編碼靈活. 后續如果有機會, 嘗試測試一下springmvc整體的QPS, 看看其作為接入層, 整體的服務能力是多少, 以及如何優化.
寫在最后:
如果你覺得這篇文章對你有幫助, 請小小打賞下. 其實我想試試, 看看寫博客能否給自己帶來一點小小的收益. 無論多少, 都是對樓主一種由衷的肯定.
