"org.springframework.web.servlet.view.BeanNameViewResolver"/>
上面的代码中:
Component-scan
启用对带有Spring注释的类进行自动扫描
在实践中,它将检查控制器类中所定义的@Controller注释。
DefaultAnnotationHanlderMappings和AnnotationMethodHandlerAdapter
使用@ReqeustMapping注释的类或函数的beans由Spring处理
这个注释将在下一节进行详细介绍。
Jaxb2Mashaller
定义使用JAXB2进行对象XML映射(OXM)的编组器(marshaller)和解组器(unmarshaller
MashallingView
定义一个使用Jaxb2Mashaller的XML表示view
BeanNameViewResolver
使用用户指定的bean名称定义一个视图解析器
本例将使用名为“employees”的MarshallingView。
这样就完成了Spring的相关配置。
下一步是编写一个控制器来处理用户请求。
清单3显示的是控制器类。
清单3.dw.spring3.rest.controller.EmployeeController
@Controller
publicclassEmployeeController{
@RequestMapping(method=RequestMethod.GET,value="/employee/{id}")
publicModelAndViewgetEmployee(@PathVariableStringid){
Employeee=employeeDS.get(Long.parseLong(id));
returnnewModelAndView(XML_VIEW_NAME,"object",e);
}
}
@RequestMapping注释是SpringREST特性的关键所在。
它指定所注释的方法将处理哪个HTTP方法(RequestMethod.GET)和哪个URI(/employee/{id})。
注意:
∙对于{id}占位符,使用@PathVariable注释可以将{}内的值注入到函数的参数。
∙XML_VIEW_NAME为employees,这是rest-servlet.xml中定义的视图名称。
∙employeeDS是一个基于内存的数据源,它的实现已经超出本文写作范围。
将Web应用发布到您的Tomcat上。
这时,您可以打开浏览器,然后输入http:
//:
//service/employee/1。
浏览器就会显示一个ID为1的员工信息的XML视图。
请继续阅读以了解更多关于SpringREST支持的特性。
方法
资源操作是通过HTTP方法实现的,如GET、POST、PUT和DELETE。
您在前面已经了解了如何使用GET方法查询员工信息。
现在我们将介绍POST、PUT和DELETE。
通过使用@RequestMapping注释的功能,处理不同方法的代码是非常相似的。
清单4显示了EmployeeController的代码片断。
清单4.dw.spring3.rest.controller.EmployeeController
@RequestMapping(method=RequestMethod.POST,value="/employee")
publicModelAndViewaddEmployee(@RequestBodyStringbody){
Sourcesource=newStreamSource(newStringReader(body));
Employeee=(Employee)jaxb2Mashaller.unmarshal(source);
employeeDS.add(e);
returnnewModelAndView(XML_VIEW_NAME,"object",e);
}
@RequestMapping(method=RequestMethod.PUT,value="/employee/{id}")
publicModelAndViewupdateEmployee(@RequestBodyStringbody){
Sourcesource=newStreamSource(newStringReader(body));
Employeee=(Employee)jaxb2Mashaller.unmarshal(source);
employeeDS.update(e);
returnnewModelAndView(XML_VIEW_NAME,"object",e);
}
@RequestMapping(method=RequestMethod.DELETE,value="/employee/{id}")
publicModelAndViewremoveEmployee(@PathVariableStringid){
employeeDS.remove(Long.parseLong(id));
Listemployees=employeeDS.getAll();
EmployeeListlist=newEmployeeList(employees);
returnnewModelAndView(XML_VIEW_NAME,"employees",list);
}
在上面的代码中:
∙RequestMethod.的值确定所注释的函数应该处理哪个HTTP方法。
∙通过@RequestBody,HTTP请求的主体内容可以作为一个参数注入。
在本例中,主体内容是表示员工信息的XML数据。
我们使用JAXB2来将XML解组为JavaBean,然后将它存储。
一个示例请求主体可以是:
3guest
∙其他可以注入到函数参数的有用的注释有@PathVariable、@RequestParm等等。
Spring文档有完整列表的注释(见参考资料)。
资源集合
通常,您还需要操作批量的资源。
例如,您可能希望获取所有员工的信息而不只是一个员工的信息。
您可以采取类似于之前情况的方法实现;您所需要做的修改就是将URI从/employee修改成/employees。
员工的复数形式能够正确反映批量的语义。
清单5显示了这种实现方法。
清单5.EmployeeController的getAllEmployees
@RequestMapping(method=RequestMethod.GET,value="/employees")
publicModelAndViewgetEmployees(){
Listemployees=employeeDS.getAll();
EmployeeListlist=newEmployeeList(employees);
returnnewModelAndView(XML_VIEW_NAME,"employees",list);
}
您需要为Employee集合声明一个包装类。
这个包装类是JAXB2所需要的,因为它无法正确地编组java.util.List类。
清单6显示了EmployeeList类。
清单6.dw.spring3.rest.bean.EmployeeList
@XmlRootElement(name="employees")
publicclassEmployeeList{
privateintcount;
privateListemployees;
publicEmployeeList(){}
publicEmployeeList(Listemployees){
this.employees=employees;
this.count=employees.size();
}
public
intgetCount(){
returncount;
}
publicvoidsetCount(intcount){
this.count=count;
}
@XmlElement(name="employee")
publicListgetEmployees(){
returnemployees;
}
publicvoidsetEmployees(Listemployees){
this.employees=employees;
}
}
内容协商
REST服务的另一个常用特性是它们能够根据请求产生不同的表示。
例如,如果客户端请求所有员工的HTML/text表示方式,那么服务器就应该为用户产生一个符合语法规则的HTML页面。
如果客户端请求的是员工的application/XML表示方式,那么服务器就应该产生一个XML结果。
其他受欢迎的表示方式还有ATOM和PDF。
Spring3引入了一个名为ContentNegotiatingViewResolver的新视图解析器。
它可以根据请求的内容类型(请求头中的Accept属性)或URI后缀来切换视图解析器。
下面的例子使用ContentNegotiatingViewResolver来实现多种表示方式的支持。
在rest-servlet.xml文件中,用注释去掉原来定义的viewResolver。
而使用ContentNegotiatingViewResolver来替代它,如清单7所示。
清单7.定义内容协商
.ContentNegotiatingViewResolver">
.BeanNameViewResolver"/>
.UrlBasedViewResolver">
"org.springframework.web.servlet.view.JstlView"/>
这个定义显示了处理两种请求内容的支持:
application/xml和text/html。
这段代码也定义了两个视图解析器:
其中BeanNameViewResolver是负责处理application/xml的,而另一个UrlBasedViewResolver则负责处理text/html。
在实践中,当您在浏览器上输入http:
//:
//service/employees,那么它就会请求text/html形式的所有员工信息。
然后UrlBasedViewResolver会进行解析,而Spring将会选择/WEB-INF/jsp/employees.jsp作为返回的视图。
当您添加请求头Accept:
application/xml并再发起请求时,那么BeanNameViewResolver就会进行解析。
如清单5中的代码,它将使用一个名为employees的视图来表示,它就是所定义的JAXB2编组器视图。
getAllEmployees()的控制器代码不需要修改。
employees.jsp将会使用名为employees的模型对象来渲染。
清单8显示了employees.jsp的代码片断。
清单8./WEB-INF/jsp中的employees.jsp
ID | Name | Email |
---|
forEachvar="employee"items="${employees.employe