公司的一个内部系统URL是restful风格的,远比我们系统的众多***.action请求格式看起来舒服。于是花了一两天研究下Spring mvc 3.0对restful风格的支持。
Spring 对REST的支持是构建于Spring MVC上的。
REST不同于RPC,RPC(DUBBO,HSF,JSF,HESSIAN)是面向服务的,重点在动作和行为。而REST是面向资源的,它将资源的状态在客户端和服务端间进行转移。URL在REST中起了关键作用。同一个URL,通过配置不同的请求方法,可以对应后台的对资源的CRUD操作(详见下面的对应关系)。RESTful的URL是有层级的,从左向右读是一个从抽象到具体,从高级到低级的构成。
path/ POST --> 新增 (CREATE)
path/id GET --> 查询 (READ)
path/id PUT --> 更新 (UPDATE)
path/id DELETE --> 删除 (DELETE)
GET是返回资源,将资源的状态从服务器转移到客户端。而PUT则恰恰相反,将资源的状态从客户端转移到服务端。POST和DELETE也正好相反,POST负责创建资源,而DELETE则负责删除资源。
RESTful的URL是参数化的URL,可以使用URL的部分值作为请求参数。@PathVariable注解则让这个功能成为现实。它的作用在于将URL中的占位符的值传到所注解的变量上。
下面我给出我实现的一个DEMO。
后台代码实现
@Log4j
@RequestMapping(value = "/word")
@Controller
public class Demo extends BaseController {
@Autowired WriteDao writeDao;
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public String update(Model model, @PathVariable Integer id, @RequestParam Integer lib_id, @RequestParam String word, RiskKeyWord key) {
writeDao.update("word.update", key);
return "word";
}
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseBody
public Integer add(Model model, RiskKeyWord key) {
Integer word = null;
try {
word = (Integer) writeDao.insert("word.add", key);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return word;
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseBody
public RiskKeyWord query(Model model, @PathVariable int id) {
RiskKeyWord word = null;
try {
word = writeDao.getObject("word.query", id);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return word;
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseBody
public int del(Model model, @PathVariable int id) {
int word = 0;
try {
word = writeDao.delete("word.del", id);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return word;
}
// 页面展示
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Model model) {
return "word";
}
}
各个方法的URL路径配置是一样的,区别在于method参数的配置,也就是不同的请求方法。
前端代码实现
function update() {
var url = "/word/" + $("#id").val();
$.ajax({
url : url,
data : $("#f").serialize(),
type : "PUT",
success : function(data, textStatus, jqXHR) {
if (data == "true") {
IM.alert("添加成功", "添加成功");
query();
IM.close();
} else {
IM.alert("添加失败", "添加失败");
}
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
IM.alert("添加失败", "添加失败");
}
});
}
这里仅给出更新操作,CRUD四个操作的js代码完全一样,除了type参数,删除对应delete,新增对应post。
web.xml配置
<filter>
<filter-name>httpPutFormFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpPutFormFilter</filter-name>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
之所以要配置HttpPutFormContentFilter,是因为spring mvc对put支持的并不好,put请求时不会解析请求体中的参数。但是配置了这个过滤器后,这个问题可以完美的解决。详细的请参见我上一篇博文
点击打开链接。