求助restlet springmvcc rest路径映射问题

您所在的位置: &
Spring REST配置指南与问题总结
Spring REST配置指南与问题总结
JavaEye博客
springmvc 3.0 中增加 RESTful URL功能,构造出类似javaeye现在的URL。本文对Spring REST的配置进行了总结,描述了其中遇到的一些问题。
下一版本的rapid-framework需要集成spring RESTful URL。最近JavaEye的badqiu对于如何搭建spring RESTful URL进行了研究,并总结问题如下。
springmvc 3.0 中增加 RESTful URL功能,构造出类似javaeye现在的URL。比如如下URL/blog/1&&HTTP&GET&=&&&&&得到id&=&1的blog &/blog/1&&HTTP&DELETE&=&&删除&id&=&1的blog &/blog/1&&HTTP&PUT&&=&&&&更新id&=&1的blog &/blog&&&&&HTTP&POST&=&&&&新增BLOG&
以下详细解一下spring rest使用.
首先,我们带着如下两个问题查看本文。
1. 如何在java构造没有扩展名的RESTful url,如 /forms/1,而不是 /forms/1.do
2. 浏览器的form标签不支持提交delete,put请求,如何曲线解决
springmvc rest 实现
springmvc的resturl是通过@RequestMapping 及@PathVariable annotation提供的,通过如@RequestMapping(value="/blog/{id}",method=RequestMethod.DELETE)即可处理/blog/1 的delete请求.@RequestMapping(value="/blog/{id}",method=RequestMethod.DELETE) &public&ModelAndView&delete(@PathVariable&Long&id,HttpServletRequest&request,HttpServletResponse&response)&{ &&blogManager.removeById(id); &&return&new&ModelAndView(LIST_ACTION); &} &&&
@RequestMapping @PathVariable如果URL中带参数,则配合使用,如@RequestMapping(value="/blog/{blogId}/message/{msgId}",method=RequestMethod.DELETE) &public&ModelAndView&delete(@PathVariable("blogId")&Long&blogId,@PathVariable("msgId")&Long&msgId,HttpServletRequest&request,HttpServletResponse&response)&{ &} &&&
spring rest配置指南
1. springmvc web.xml配置&!--&该servlet为tomcat,jetty等容器提供,将静态资源映射从/改为/static/目录,如原来访问&http://localhost/foo.css&,现在http://localhost/static/foo.css&--&&&&&default&/servlet-name&&&/static/*&/url-pattern&&/servlet-mapping&&&&&&&&springmvc&/servlet-name&&&&&&org.springframework.web.servlet.DispatcherServlet&/servlet-class&&&&&&1&/load-on-startup&&/servlet&&&!--&URL重写filter,用于将访问静态资源http://localhost/foo.css&转为http://localhost/static/foo.css&--&&&&&UrlRewriteFilter&/filter-name&&&org.tuckey.web.filters.urlrewrite.UrlRewriteFilter&/filter-class&&&&&&&&&&&confReloadCheckInterval&/param-name&&&&&&&&60&/param-value&&&&&&&/init-param&&&&&&&&&&&&&&&&&&logLevel&/param-name&&&&&&&&&&&&&&&DEBUG&/param-value&&&&&&&&&&/init-param&&&&& &&/filter&&&&&UrlRewriteFilter&/filter-name&&&/*&/url-pattern&&/filter-mapping&&&!--&覆盖default&servlet的/,&springmvc&servlet将处理原来处理静态资源的映射&--&&&&&&&&springmvc&/servlet-name&&&&&&/&/url-pattern&&/servlet-mapping&&&!--&浏览器不支持put,delete等method,由该filter将/blog?_method=delete转换为标准的http&delete方法&--&&&&&HiddenHttpMethodFilter&/filter-name&&&org.springframework.web.filter.HiddenHttpMethodFilter&/filter-class&&/filter&&&&&&HiddenHttpMethodFilter&/filter-name&&&springmvc&/servlet-name&&/filter-mapping&
2. webapp/WEB-INF/springmvc-servlet.xml配置,使用如下两个class激活@RequestMapping annotation&&class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"&&&class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"&
完整配置&&default-autowire="byName"&&&&&&&!--&自动搜索@Controller标注的类&--&&&&base-package="com.**.controller"&& &&&&&&&class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"&&&&&&&&class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"&&&&&&&!--&Default&ViewResolver&--&&&&&&&id="viewResolver"&class="org.springframework.web.servlet.view.InternalResourceViewResolver"&&&&&&&&&&&name="viewClass"&value="org.springframework.web.servlet.view.JstlView"&&&&&&&&&&&name="prefix"&value="/pages"&&&&&&&&&&&name="suffix"&value=".jsp"&/property&&&&&&/bean&&&&& &&&&&&&id="messageSource"&class="org.springframework.context.support.ResourceBundleMessageSource"&p:basename="i18n/messages"&&&&&&&!--&Mapping&exception&to&the&handler&view&--&&&&&&&id="exceptionResolver"&class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"&&&&&&&!--&to&/commons/error.jsp&--&&&&&&&&&&&name="defaultErrorView"&value="/commons/error"&&&&&&&&&&&name="exceptionMappings"&&&&&&&&&&&&&&&&&&&&&&&&&&&&/props&&&&&&&&&&/property&&&&&&/bean&&&&&&&&& &&/beans&& &
3. Controller编写&&&&@Controller&@RequestMapping("/userinfo") &public&class&UserInfoController&extends&BaseSpringController{ &&&&protected&static&final&String&DEFAULT_SORT_COLUMNS&=&null;& && &&private&UserInfoManager&userInfoM && &&private&final&String&LIST_ACTION&=&"redirect:/userinfo"; && &&&&&&public&void&setUserInfoManager(UserInfoManager&manager)&{ &&&this.userInfoManager&=& &&} && &&&&@RequestMapping&&public&ModelAndView&index(HttpServletRequest&request,HttpServletResponse&response,UserInfo&userInfo)&{ &&&PageRequest&&Map&&pageRequest&=&newPageRequest(request,DEFAULT_SORT_COLUMNS); &&&&&& &&&Page&page&=&this.userInfoManager.findByPageRequest(pageRequest); &&&savePage(page,pageRequest,request); &&&return&new&ModelAndView("/userinfo/list","userInfo",userInfo); &&} && &&&&@RequestMapping(value="/new") &&public&ModelAndView&_new(HttpServletRequest&request,HttpServletResponse&response,UserInfo&userInfo)&throws&Exception&{ &&&return&new&ModelAndView("/userinfo/new","userInfo",userInfo); &&} && &&&&@RequestMapping(value="/{id}") &&public&ModelAndView&show(@PathVariable&Long&id,HttpServletRequest&request,HttpServletResponse&response)&throws&Exception&{ &&&UserInfo&userInfo&=&(UserInfo)userInfoManager.getById(id); &&&return&new&ModelAndView("/userinfo/show","userInfo",userInfo); &&} && &&&&@RequestMapping(value="/{id}/edit") &&public&ModelAndView&edit(@PathVariable&Long&id,HttpServletRequest&request,HttpServletResponse&response)&throws&Exception&{ &&&UserInfo&userInfo&=&(UserInfo)userInfoManager.getById(id); &&&return&new&ModelAndView("/userinfo/edit","userInfo",userInfo); &&} && &&&&@RequestMapping(method=RequestMethod.POST) &&public&ModelAndView&create(HttpServletRequest&request,HttpServletResponse&response,UserInfo&userInfo)&throws&Exception&{ &&&userInfoManager.save(userInfo); &&&return&new&ModelAndView(LIST_ACTION); &&} && &&&&@RequestMapping(value="/{id}",method=RequestMethod.PUT) &&public&ModelAndView&update(@PathVariable&Long&id,HttpServletRequest&request,HttpServletResponse&response)&throws&Exception&{ &&&UserInfo&userInfo&=&(UserInfo)userInfoManager.getById(id); &&&bind(request,userInfo); &&&userInfoManager.update(userInfo); &&&return&new&ModelAndView(LIST_ACTION); &&} && &&&&@RequestMapping(value="/{id}",method=RequestMethod.DELETE) &&public&ModelAndView&delete(@PathVariable&Long&id,HttpServletRequest&request,HttpServletResponse&response)&{ &&&userInfoManager.removeById(id); &&&return&new&ModelAndView(LIST_ACTION); &&} &&&&&@RequestMapping(method=RequestMethod.DELETE) &&public&ModelAndView&batchDelete(HttpServletRequest&request,HttpServletResponse&response)&{ &&&String[]&items&=&request.getParameterValues("items"); &&&for(int&i&=&0;&i&&&&items.&i++)&{ &&&&java.lang.Long&id&=&new&java.lang.Long(items[i]); &&&&userInfoManager.removeById(id); &&&} &&&return&new&ModelAndView(LIST_ACTION); &&} && &} && &
上面是rapid-framework 新版本生成器生成的代码,以后也将应用此规则,rest url中增删改查等基本方法与Controller的方法映射规则/userinfo&&&&=&&index() &/userinfo/new&&=&&_new() &/userinfo/{id}&&=&&show() &/userinfo/{id}/edit&&&=&&edit() &/userinfo&&POST&&=&&create() &/userinfo/{id}&&PUT&=&&update() &/userinfo/{id}&&DELETE&=&&delete() &/userinfo&&DELETE&&=&&batchDelete() &
注(不使用 /userinfo/add& =& add() 方法是由于add这个方法会被maxthon浏览器当做广告链接过滤掉,因为包含ad字符)
4. jsp 编写&&action="${ctx}/userinfo/${userInfo.userId}"&method="put"&&/form:form&&将生成一个hidden的_method=put,并于web.xml中的HiddenHttpMethodFilter配合使用,在服务端将post请求改为put请求 &&&&id="userInfo"&action="/springmvc_rest_demo/userinfo/2"&method="post"&&&&type="hidden"&name="_method"&value="put"&&/form&& &
另外一种方法是你可以使用ajax发送put,delete请求.
5. 静态资源的URL重写
如上我们描述,现因为将default servlet映射至/static/的子目录,现我们访问静态资源将会带一个/static/前缀.
如 /foo.gif, 现在访问该文件将是 /static/foo.gif.
那如何避免这个前缀呢,那就是应用URL rewrite,现我们使用 , 重写规则如下&&&&&&&!--&访问jsp及jspx将不rewrite&url,其它.js,.css,.gif等将重写,如&/foo.gif&=&/static/foo.gif&--&&&&&&&&&&&&&&operator="notequal"&next="and"&type="request-uri".*.jsp&/condition&&&&&&&&operator="notequal"&next="and"&type="request-uri".*.jspx&/condition&&&&&&&&&&^(/.*\..*)$&/from&&&&&&&&&&/static$1&/to&&&&&&/rule&&/urlrewrite&&&&&
另笔者专门写了一个 RestUrlRewriteFilter来做同样的事件,以后会随着rapid-framework一周发布. 比这个更加轻量级.
并且该代码已经贡献给spring,不知会不会在下一版本发布。
【编辑推荐】
【责任编辑: TEL:(010)】
关于的更多文章
AngularJS是很多Web开发人员在打造单页面应用程序时的首选创建方
所以姑娘,让我们做一枚花见花开的程序媛。
讲师: 4人学习过讲师: 7人学习过讲师: 66人学习过
很显然,Oracle已正在开发Java 9。Java 9主要的增强内
一个好的工具无论是对于开发者还是整个项目而言,都是
在此之前的几年时间里,已经有很多开发者陆续使用了HT
Java的出现,实现了跨操作系统平台的程序开发,以Java为基础的J2EE技术已经成为因特网服务技术的主流。然而,以J2EE为基础的SOA
51CTO旗下网站<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&求助springmvc rest路径映射问题_百度知道
求助springmvc rest路径映射问题
提问者采纳
接在方法前配置就好了@RequestMapping(value = &user//list&quot
来自团队:
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁SpringMVC使用Rest风格,静态资源访问路径问题,不是要解答无法访问资源的问题
[问题点数:100分]
SpringMVC使用Rest风格,静态资源访问路径问题,不是要解答无法访问资源的问题
[问题点数:100分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2016年1月 Java大版内专家分月排行榜第一2015年12月 Java大版内专家分月排行榜第一2015年9月 Java大版内专家分月排行榜第一2015年8月 Java大版内专家分月排行榜第一
2016年3月 Java大版内专家分月排行榜第二2016年2月 Java大版内专家分月排行榜第二2015年11月 Java大版内专家分月排行榜第二2015年10月 Java大版内专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。[转载]使用Spring&MVC&搭建Rest服务
使用Spring MVC 搭建Rest服务
本文由大关总结整理所得,不保证内容的正确性,转载请标明出处!
Rest(Representational State
Transfer,表述状态转移),是一种基于Http协议的,能够快速开发网络服务程序,并且提高网络服务系统伸展性的设计和开发方式。Rest的两端可以是不同构的编程和程序运行环境,Rest通过Http协议将通信的两端进行连接,在服务两端通过对Http协议的使用,最终完成数据的翻译和转换。
Rest有几个重要的特点,使得Rest能够在服务搭建上占有一定的优势。首先,Rest以一切皆资源的方式来看待所有的web提供的服务(包括web服务本身,以及web服务中某个具体的服务应用),所有的资源都采用URI进行定位。其次,Rest通过对Http中相应字段属性设置,确定客户端和服务端的缓存策略,在一定程度上,可以缓解服务器和客户端的压力(Rest服务被认为是无状态的web服务),最后,Rest通过对Http消息体中(MIME)Content-Type的内容不同,可以采用不同处理策略对消息分解,获取需要的信息,此外Rest还有很多优势,具体可以参考:Architectural
Styles and the Design of Network-based Software
Architectures这篇论文,文中详细描述了Rest服务的推导过程。
要想使用Rest必须要了解Http服务中定义的几个关键的方法。GET,用于从服务端获取信息,但并不更改服务端的任何状态;POST,用于提交创建的信息,一般更改服务端的数据状态,并且返回新创建对象的ID(一般来说,为了保证ID的唯一性,ID的值需要由服务端来确定,因此在创建结束后会将新分配的ID反馈给客户端);PUT,用于更改服务端某个对象的状态(一般被认为是Update),服务端状态受到影响,不需要返回影响后的结果;DELETE,删除服务端的对象,服务端的状态发生改变,可以返回删除后的对象,也可以不返回。(Http还有其他的方法,但在Rest中不是很常用,可以查看RFC2616)。这些方法仅是意义上这样说,但是并不是一定要这用,具体的方法对应的动作完全是服务两端确定的。
在JAVA中搭建Rest服务有很多种,其中JAX-RS是JAVA定义的Rest服务的API,可以使用Apache实现的jersy搭建Rest服务。在Spring
MVC中也提供了搭建Rest服务的方法,下文主要探讨如何使用Spring MVC搭建Rest服务。
下面的内容需要您对如下内容有所了解:
(1)& 会使用Spring框架,理解依赖注入原理,理解Spring的基本配置。
使用过Java相关的Web容器(例如,Tomcat或Apache等,这里使用的是Jetty,原理相同)
(3)& 会使用一款OXM框架(例如:Castor或JAXB,这里使用的是JAXB2)
(4)& 对什么是Http服务和什么是Rest服务略有了解
如果您完全满足上面的条件,那么理解下面的内容就根本不成问题,如果您对有些内容不是很清楚,可以先看整个服务的流程,具体细节可以略看。
1.& Rest功能说明
下面我们将开始使用Spring
MVC的方法搭建一个Rest服务,在这个服务中,服务器端维护了一个关于Student的集合,客户端可以通过连接到服务端,向服务端添加、删除、查找和更新学生信息等操作。
2.& 学生数据结构(bean)
通过对Rest功能的分析,可以看出,服务端有两个关键的数据结构,一个是用来表示学生信息的Student类,另外一个是用来表示学生集合的StudentList类。下面我们通过schema定义这两个数据结构。
StudentLists.xsd
&?xml version="1.0"
encoding="UTF-8"?&
&xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"&
&xsd:complexType
name="student"&
&xsd:sequence&
&&&&&&&&&&&&&
&xsd:element name="name"
type="xsd:string" minOccurs="1"/&
&&&&&&&&&&&&&
&xsd:element name="age"
type="xsd:int"/&
&&&&&&&&&&
&/xsd:sequence&
&&&&&&&&&&
&xsd:attribute name="id"
type="xsd:string" use="required"/&
&/xsd:complexType&
&xsd:element
name="studentList"&
&xsd:complexType&
&&&&&&&&&&
&xsd:sequence&
&&&&&&&&&&&&&
&xsd:element name="students"
type="student"&
maxOccurs="unbounded"/&
&&&&&&&&&&
&/xsd:sequence&
&/xsd:complexType&
&/xsd:element&
&/xsd:schema&
可以看出,schema中定义了两个结构,一个是学生类型,一个是学生集合类型。学生类型包括两个元素(分别是name和age)和一个属性(id)。学生集合类型中仅包含一个元素(students,是一个学生类型的集合)。
通过使用xjc生成java类,xjc命令如下:
I:programseclipseSpringMVCRestTestsrc&xjc -p
com.upc.upcgrid.guan.springMvcR
estTest.bean.student StudentLists.xsd
xjc(xml to java
compiler),可以将schema转换成java类,-p后面的两个参数分别是转换后的包名,以及需要转换的schema文件名字。此时,你刷新你的服务,可以看到xjc已经生成了Student类和StudentLists类,此外还生成了一个ObjectFactory类,这里我们不需要ObjectFactory类,因此直接将这个类删除,之后在Student类的声明前增加一条语句,使得Student类声明部分如下:
@XmlType(name = "student", propOrder = {
&&& "name",
@XmlRootElement(name="student")
public class Student {
3.& 学生管理类
学生的基本结构已经搭建完成,现在需要提供一个管理类,用于来管理学生集合(注意,正常情况下,应当将学生数据存入数据库,这里为了简化,仅将这些信息出入一个Map中进行管理)。学生管理类维护这学生集合,以及基于集合之上的操作。
StudentManager.java
@Component
public class StudentManager {
Map&String, Student& students =
new ConcurrentHashMap&String,
Student&();
public synchronized void addStudent(Student
if(students.containsKey(student.getId()))
&&&&&&&&&&
students.put(student.getId(), student);
public synchronized void deleteStudent(String
if(students.containsKey(id))
&&&&&&&&&&
students.remove(id);
public synchronized void updateStudent(String
id,Student student){
deleteStudent(id);
if(student.getId()==null ||
student.getId().equals(""))
&&&&&&&&&&
student.setId(id);
addStudent(student);
public synchronized Student getStudent(String
return students.get(id);
public synchronized StudentList getStudent() {
StudentList sl = new StudentList();
for(String key : students.keySet())
&&&&&&&&&&
sl.getStudents().add(students.get(key));
可以看出,我们将StudentManager标记成component,以便Spring能够将这个类的实例注入到使用它的类中(注意,这个类必须是一个单例模式,因为这个类中维护着学生的集合)。此外,StudentManager中的所有方法都标记成了同步方法,并且Map集合也是一个同步集合。StudentManager提供了对学生集合Map的基本操作。
4.& Rest服务实现
下面提供了使用Spring MVC实现Rest服务的方法。
@Controller
@RequestMapping(value="/students")
public class StudentServer {
private StudentM
@RequestMapping(method=RequestMethod.POST)
@ResponseBody
public String createStudent(@RequestBody Student
manager.addStudent(student);
return student.getId();
@RequestMapping(value="/{id}",method=RequestMethod.GET)
@ResponseBody
public Student getStudent(@PathVariable String id){
return manager.getStudent(id);
@RequestMapping(method=RequestMethod.GET)
@ResponseBody
public StudentList getStudent(){
return manager.getStudent();
@RequestMapping(value="/{id}",method=RequestMethod.PUT)
@ResponseBody
public void updateStudent(@RequestBody Student
student,@PathVariable String id){
manager.updateStudent(id, student);
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
@ResponseBody
public void deleteStudent(@PathVariable String
manager.deleteStudent(id);
@Autowired
public void setManager(StudentManager manager) {
this.manager =
用Control标记,Spring会认为这是一个Web服务,使用RequestMapping指明了服务映射的URI内容和映射的Http请求的方法。使用PathVariable可以从URI中获取参数,使用RequestBody,Spring会将Http消息体内部的数据使用配置策略转换成一个对象(参考5.
Spring的配置),使用ResponseBody,Spring会将返回值转换成消息体需要的格式(参考5.Spring的配置)。
5.& Spring的配置
现在,我们需要对Spring进行基本的配置,以便Spring能够使用正确的方式对接收到(发送出)的Http请求(相应)使用正确的方法处理(生成)消息体。我们的基本策略是,如果接收到的是XML文档(即Content-type是***/xml类型),则使用JAXB2将消息体转换成对象,否则将消息体作为普通文本进行处理;如果要发送的消息是复杂对象(不是简单类型,例如:String、Integer、void等),则将消息使用JAXB2进行编组,否则仅生成文本消息。
Spring的配置如下:
SpringConfig.java
@Configuration
public class SpringConfig {
private Jaxb2M
public @Bean Jaxb2Marshaller
jaxb2Marshaller()//配置JAXB2Context
Jaxb2Marshaller marshaller = new
Jaxb2Marshaller();//创建JAXB上下文环境
marshaller.setClassesToBeBound(Student.class,StudentList.class);//映射的xml类放入JAXB环境中&&&&
this.marshaller =
public @Bean AnnotationMethodHandlerAdapter
annotationMethodHandlerAdapter()
AnnotationMethodHandlerAdapter adapter = new
AnnotationMethodHandlerAdapter();//创建消息体转换器
HttpMessageConverter&?&[] converters
HttpMessageConverter&?&[2];//创建转换数组
StringHttpMessageConverter stringConverter = new
StringHttpMessageConverter();//创建字符转换器
MarshallingHttpMessageConverter marshallerConverter = new
MarshallingHttpMessageConverter();//创建xom转换器
marshallerConverter.setMarshaller(marshaller);//设置marshaller
marshallerConverter.setUnmarshaller(marshaller);//设置unmarshaller
//将两个转换器放入列表
converters[0] = (stringConverter);
converters[1] = (marshallerConverter);
//将转换器列表赋值给消息体转换器
adapter.setMessageConverters(converters);
//返回消息体转换器&&
SpringConfig中先配置了JAXB2,在JAXB2中需要指定在2学生数据结构中生成的两个类,因此JAXB环境会知道如何将Student和StudentList编组和解组。
SpringConfig中还配置了一个Adapter,这个转换器是Spring用来转换消息体时使用的,在这里,我们为Adapter配置了两个Converter,一个使用来处理XML的Marshaller的Converter,一个是用来处理普通类型String的Converter。因此Spring会根据情况,选择正确的Converter处理消息体。(注意,只要你提供了一个Adapter,Spring就会使用你提供的这个Adapter处理消息体,如果你没有提供,Spring将会使用默认的Adapter处理消息体,由于对于XML类型(或者JSON类型)的数据必须手动提供Converter,所以这里不能使用默认的Converter)。
之后是Spring的配置文件:
rest-servlet.xml
&?xml version="1.0"
encoding="UTF-8"?&
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
&&&&&&&&&&
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
&&&&&&&&&&
http://www.springframework.org/schema/aop
&&&&&&&&&&
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
&&&&&&&&&&
http://www.springframework.org/schema/tx
&&&&&&&&&&
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
&&&&&&&&&&
http://www.springframework.org/schema/context
&&&&&&&&&&
http://www.springframework.org/schema/context/spring-context-2.5.xsd"&
&&&&&&&&&&
&context:annotation-config/&
&&&&&&&&&&
&context:component-scan
base-package="com.upc.upcgrid.guan"/&&&&&&&&&&&&&&&&&
Spring的配置文档中,仅让Spring环境扫描标有标记类的包。
&?xml version="1.0"
encoding="UTF-8"?&
&web-app version="2.5"
xmlns="/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="/xml/ns/javaee
/xml/ns/javaee/web-app_2_5.xsd"&
&servlet-name&rest&/servlet-name&
&servlet-class&org.springframework.web.servlet.DispatcherServlet&/servlet-class&
&init-param&
&&&&&&&&&&
&param-name&contextConfigLocation&/param-name&
&&&&&&&&&&
&param-value&/conf/rest-servlet.xml&/param-value&
&/init-param&
&load-on-startup&1&/load-on-startup&
&/servlet&
&servlet-mapping&
&servlet-name&rest&/servlet-name&
&url-pattern&/rest/*&/url-pattern&
&/servlet-mapping&&&
&/web-app&
Spring使用DispatcherServlet完成URI任务的匹配和分发,在创建DispatcherServlet的时候,提供了Spring配置文件的路径。
6.& Jetty服务器的配置和启动
我们这里使用较轻量级的Jetty服务器,以嵌入式的方式启动Spring服务。Jetty服务要比Tomcat小的多,并且无需安装,可以嵌入到程序中执行。下面给出Jetty的启动过程。
JettyServerStart.java
public class JettyServerStart {
public static void main(String[] args) {
&Server server= new
Server();//创建jetty web容器(这与tomcat容器类似)
server.setStopAtShutdown(true);//在退出程序是关闭服务
//创建连接器,每个连接器都是由IP地址和端口号组成,连接到连接器的连接将会被jetty处理
//第一个连接器的连接方式为http://202.194.158.128:8586
Connector connector = new
SelectChannelConnector();//创建一个连接器
connector.setPort(8586);//连接的端口号,(tomcat下)一般是8080,这里根据服务需求进行设置
connector.setHost("202.194.158.128");//ip地址
server.addConnector(connector);//添加连接
//创建本地连接器,连接方式为http://localhost:8585
Connector connectorLocal = new SelectChannelConnector();
connectorLocal.setPort(8585);
connectorLocal.setHost("localhost");
server.addConnector(connectorLocal);
//配置rest服务
WebAppContext context = new WebAppContext();//创建服务上下文
context.setContextPath("/SpringMVCRestTest");//访问服务路径
http://{ip}:8568/SpringMVCRestTest
context.setConfigurationDiscovered(true);
context.setDescriptor(System.getProperty("user.dir")+File.separator+"conf"+File.separator+"web.xml");//指明服务描述文件,就是web.xml
context.setResourceBase(System.getProperty("user.dir"));//指定服务的资源根路径,配置文件的相对路径与服务根路径有关
server.setHandler(context);//添加处理
&&&&&&&&&&
server.start();//开启服务
&&&&&&&&&&
server.join();
} catch (Exception e) {
&&&&&&&&&&
e.printStackTrace();
&&&&&&&&&&
System.exit(1);
}//开启服务
现在,我们执行main方法,会的到如下输出:
21:22:07.609:INFO::jetty-7.3.0.v
21:22:07.796:INFO::NO JSP Support for
/SpringMVCRestTest, did not find
org.apache.jasper.servlet.JspServlet
21:22:07.921:INFO::started
o.e.j.w.WebAppContext{/SpringMVCRestTest,file:/I:/programs/eclipse/SpringMVCRestTest/}
21:22:08.093:INFO:/SpringMVCRestTest:Initializing Spring
FrameworkServlet 'rest'
org.springframework.web.servlet.FrameworkServlet
initServletBean
信息: FrameworkServlet 'rest': initialization
org.springframework.context.support.AbstractApplicationContext
prepareRefresh
信息: Refreshing WebApplicationContext for namespace
'rest-servlet': startup date [Fri Jun 24 21:22:08 CST 2011]; root
of context hierarchy
org.springframework.beans.factory.xml.XmlBeanDefinitionReader
loadBeanDefinitions
信息: Loading XML bean definitions from
ServletContext resource [/conf/rest-servlet.xml]
org.springframework.beans.factory.support.DefaultListableBeanFactory
preInstantiateSingletons
信息: Pre-instantiating singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory@7736bd:
defining beans
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springConfig,studentManager,studentServer,jaxb2Marshaller,annotationMethodHandlerAdapter];
root of factory hierarchy
org.springframework.oxm.jaxb.Jaxb2Marshaller
createJaxbContextFromClasses
信息: Creating JAXBContext with classes to be bound
com.upc.upcgrid.guan.springMvcRestTest.bean.student.Student,class
com.upc.upcgrid.guan.springMvcRestTest.bean.student.StudentList]
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
registerHandler
信息: Mapped URL path [/students/{id}] onto handler
[com.upc.upcgrid.guan.springMvcRestTest.spring.StudentServer@497904]
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
registerHandler
信息: Mapped URL path [/students/{id}.*] onto handler
[com.upc.upcgrid.guan.springMvcRestTest.spring.StudentServer@497904]
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
registerHandler
信息: Mapped URL path [/students/{id}/] onto handler
[com.upc.upcgrid.guan.springMvcRestTest.spring.StudentServer@497904]
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
registerHandler
信息: Mapped URL path [/students] onto handler
[com.upc.upcgrid.guan.springMvcRestTest.spring.StudentServer@497904]
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
registerHandler
信息: Mapped URL path [/students.*] onto handler
[com.upc.upcgrid.guan.springMvcRestTest.spring.StudentServer@497904]
org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
registerHandler
信息: Mapped URL path [/students/] onto handler
[com.upc.upcgrid.guan.springMvcRestTest.spring.StudentServer@497904]
org.springframework.web.servlet.FrameworkServlet
initServletBean
信息: FrameworkServlet 'rest': initialization
completed in 969 ms
21:22:09.125:INFO::Started
SelectChannelConnector@202.194.158.128:8586
21:22:09.125:INFO::Started
SelectChannelConnector@localhost:8585
从输出的内容可以看出,Spring服务已经正常启动,并且Jetty将会在本地的两个端口进行监听。
7.& 编写客户端测试程序
Rest的客户端可以使用Spring的RestTemplate进行编写。为了给使用这屏蔽掉我们后台与服务器进行通信的复杂操作,我们编写了一个RestUtility,这个类主要完成与服务器的通信。
RestUtility.java
public class RestUtility {
private static String url =
"http://202.194.158.128:8586/SpringMVCRestTest/rest/students/";&&&
private static RestTemplate restTemplate;
createRestTemplate();
public static RestTemplate
getRestTemplate(){&&&
return restTemplate;
private static void createRestTemplate() {
restTemplate = new RestTemplate();
List&HttpMessageConverter&?&&
converters = new
ArrayList&HttpMessageConverter&?&&();//消息体转换器列表
MarshallingHttpMessageConverter marshalConverter = new
MarshallingHttpMessageConverter();//xom类型的消息体转换器
Jaxb2Marshaller marshaller = new
Jaxb2Marshaller();//创建JAXB2类型的xom环境
marshaller.setClassesToBeBound(Student.class,StudentList.class);//将类绑定到JAXB2
marshalConverter.setMarshaller(marshaller);//设置编组器
marshalConverter.setUnmarshaller(marshaller);//设置解组器
converters.add(marshalConverter);//将xom消息体转换器添加到列表&
converters.add(new StringHttpMessageConverter());
restTemplate.setMessageConverters(converters);//将转换器列表放入RestTemplate
public static void addStudent(Student student)
throws RestClientException, URISyntaxException{
System.out.println(restTemplate.postForObject(new
URI(url), student,String.class));
public static Student getStudent(String id){
return restTemplate.getForObject(url+"{id}",
Student.class, id);
public static void updateStudent(String
id,Student student){
restTemplate.put(url+"{id}", student, id);
public static void deleteStudent(String
restTemplate.delete(url+"{id}", id);
public static StudentList getAllStudents()
throws RestClientException, URISyntaxException{
return restTemplate.getForObject(new
URI(url),StudentList.class);
这个类主要使用RestTemplate对服务器进行通信的。
最后给出一个测试程序,并给出结果.
public class RestClient {
public static void main(String[] args)
throws RestClientException, URISyntaxException {
Student student = new Student();
student.setAge(20);
student.setName("Mary");
student.setId("");&
RestUtility.addStudent(student);&&&&&&
student.setAge(21);
student.setName("Lucy");
student.setId("");
RestUtility.addStudent(student);
student = RestUtility.getStudent("");
System.err.println(student.getName());
StudentList sl = RestUtility.getAllStudents();
for(Student s : sl.getStudents())
&&&&&&&&&&
System.err.println(s.getName());
在测试程序中,我们先创建了两个学生,并将两个学生添加到远程,之后从远程查询了一个学生,并输出信息,然后查询了所有学生,输出信息。整个过程没有对错误进行处理。
执行输出:
org.springframework.oxm.jaxb.Jaxb2Marshaller
createJaxbContextFromClasses
信息: Creating JAXBContext with classes to be bound
com.upc.upcgrid.guan.springMvcRestTest.bean.student.Student,class
com.upc.upcgrid.guan.springMvcRestTest.bean.student.StudentList]
8.& 程序结构
Spring3.0官方文档
&&& Spring
MVC与JAX-RS对比:
教材:Restful Java with JAX-RS
论文:Architectural Styles and the Design of Network-based Software
Architectures
源码下载:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 spring mvc 实现rest 的文章

 

随机推荐