背景
当前的开放服务平台发展趋势,是服务使用者变得多种多样,其中既有各种前端设备(台式机、手机等),又有各种后端服务器,因此必须有一个统一的机制,方便各种服务使用者和开放服务平台进行通信。为了更好的实现开放服务平台,为了更加方便快捷的为公司内部以及外部人员提供智思、全文检索、雷达等服务,同时更加细致化的对数据中心各项服务的使用进行管理,并适应各种各样的服务使用者。因此,从开发角度考虑,团队非常需要使用一个符合开放服务平台需求的底层架构,来实现上述目标,同时还要考虑是否可以成为现有服务平台(struts)的底层框架。
在web中,服务器中的各种资源(图片、音频、网页、服务)都可以通过URI进行定位。开放服务平台中的服务也是如此。结构设计良好的URI,可极大的方便用户对于web资源的理解。用户在使用各种web资源时,还需明确各种web资源的表现形式,比如json、xml、html,这样服务器便可以根据用户指定的数据表现形式,返回不同格式的内容。设计良好的URI,以及确定的资源表现形式,可以极大的规范web资源的开发以及使用方式。
当用户使用web资源时,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到web资源的数据和状态的变化。用户大多使用HTTP协议访问web资源,HTTP协议是一个无状态的协议。这意味着,客户端操作web资源时,需要指明web资源的操作方式(GET、POST、PUT、DELETE)。此时客户端和服务端是不会维护通话状态的。在传统的网站开发中,开发者编程满足最多的便是动态web服务的GET和POST操作,静态资源则由HTTP服务器管理。
REST架构,作为一种URI设计风格的指导,以及web服务开发方式的指导,非常适合作为开放服务平台的底层架构实现指导。基于此,团队决定对现有的符合REST风格的RESTful框架进行调研,在对主流RESTful框架进行细致化的比较对比后,决定未来开放服务平台的底层技术是采用现有的实现良好的RESTful框架,还是自主开发一个更加符合开放服务平台特点、以及团队开发人员习惯的框架。[1]
REST概念
REST,representational state transfer , 字面理解为“表述性状态转移”。举例说明。
服务器保存有一个用户的信息,用户id为1,性别为男。用户通过浏览器,发送一个HTTP GET请求,获取了id为1的用户信息,并将此信息保存在浏览器中。现在用户通过浏览器,将此用户的性别修改为了女,于是浏览器通过发送一个HTTP POST请求到服务器,并带有用户的id信息和修改后的性别信息。服务器收到HTTP POST请求后,更新服务器端的用户信息。这就是所谓的状态转移,表述性指的是状态的描述方式,json或者xml都可以。
其中,状态转移时所使用的动词,都是http method的内容,而资源的URI中不会有动词。
在目前主流的三种web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。注意,REST并没有一个明确的标准,而是一种设计风格。[2]
REST的URI设计风格示例
在REST风格的URI设计中,最重要的一个原则: nouns (not verbs!) ,名词(而不是动词)。所有动词全部放置在http方法名称中。
一个简单REST风格的CRUD
l GET /users - 获取所有用户列表
l GET /users/1 - 获取ID为1的用户
l POST /users - 创建一个用户
l PUT /users/1 - 修改ID为1的用户
l DELETE /users/1 - 删除ID为1的用户
上述URI只是一种设计风格,我们依然可以使用传统mvc的URI设计风格。
l /user-list.do - 获取所有用户列表
l /user-list.do?ID=1 - 获取ID为1的用户
l /user-add.do?name=*** - 创建一个用户
l /user-edit.do?ID=1&name=*** - 修改ID为1的用户
l /user-delete.do?ID=1 - 删除ID为1的用户
在mvc风格的URI设计中,将所有的动词放置到了URI中,而不是http的方法名称中,而方法名称主要使用GET和POST,并且此两种方法对于使用mvc风格URI定位的web服务无本质区别。
注意,URI的设计风格,并不影响用户对于网络资源的认识,以及web服务的开发。
web资源的表现形式
常见的web资源表现形式有html、xml以及json等文本表现形式,以及image、wav等图片、音视频等表现形式。
在web服务中,经常使用的资源表现形式主要为html、xml和json。
其中html(超文本标记语言)主要在网页服务中使用,用于网页数据的填充,同时css完成网页内容的展现方式。
Xml(扩展标记语言)在基于SAOP协议的web service中以及xml-RPC中使用较多。由于xml可以实现语义化,因此其可以保存更加丰富的数据。
Json(JavaScript Object Notation)作为一种javascript中数据交换格式,虽然失去了语义标签,但变得更加轻量,更加易于机器解析和生成,同时占用更少的存储空间。[3]
在RESTful框架中,推荐使用json格式的数据表现形式,因为json可以很好的同javascript兼容。
调研的RESTful框架列表
名称 |
网站 |
Spring MVC |
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/ |
Jersey |
https://jersey.java.net/documentation/latest/user-guide.html |
Axis2 |
http://axis.apache.org/axis2/java/core/docs/toc.html |
Argo |
http://www.oschina.net/p/argo |
Dropwizard |
http://www.dropwizard.io/ |
Struts2 RESTful |
https://cwiki.apache.org/confluence/display/WW/REST+Plugin |
考虑到框架使用的难易程度、灵活性,以及框架上手的难易程度,本文将从以下几个方面,对以上六个Restful框架进行调研。
1、 web服务URI映射配置方式难易度;
2、 数据绑定是否自动化;
3、 是否支持Map和List格式的数据绑定;
4、 返回数据序列化是否自动化;
5、 是否支持后端模板渲染;
6、 网络资料是否充足;
7、 可否自动生成web服务客户端代码(java以及其他编程语言);
8、 是否可以成为现有服务平台的底层框架。
调研结果
Spring MVC
调研目标 |
结果 |
web服务URI映射配置方式难易度 |
使用注解方式,零配置(指定扫描的包名即可) |
数据绑定是否自动化 |
是(支持各种复杂结构,自定义Bean) |
是否支持Map和List格式的数据绑定 |
是 |
返回数据序列化是否自动化 |
是(根据contentType自动完成) |
是否支持后端模板渲染 |
是(jsp、freemaker等) |
网络资料是否充足 |
充足 |
可否自动生成web服务客户端代码(java等) |
否(但可以自己写程序,完成这部分工作) |
是否可以成为现有服务平台的底层框架 |
需对现有服务平台的jsp页面等进行修改 |
简介
Spring MVC框架是有一个MVC框架,是在springframework基础上实现的。通过实现Model-View-Controller模式来很好地将数据、业务与展现进行分离。从这样一个角度来说,Spring MVC和Struts、Struts2非常类似。[4]
URI映射
通过以@Controller注解标记控制类,使用@RequestMapping注解将方法映射到某些请求路径上,即可完成URI的映射定义,此过程不需要编写配置文件。
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class HelloController {
@RequestMapping(value="/hello",method=RequestMethod.GET)
public String sayHello(Model model) {
model.addAttribute("msg", "Hello, World!");
return "hello";
}
}
数据绑定
有多种数据绑定方式:
1、 基本数据类型、包装数据类型绑定。
只要传输的参数名同Controller中方法参数定义的名称相同,即可自动完成绑定。如果名称不一致,需要使用@RequestParam注解。注意,传输的参数可能为null。基本类型和包装类型的处理方式不同,基本类型会报错,包装类型值为null。
2、 自定义对象类型
只需将对象的属性名和表单里面的input的name值一一匹配即可。
3、 自定义复合对象类型(自定义对象中,包含自定义对象)
只需要使用“属性名(对象类型的属性).属性名”来命名input的name即可。
例:
@InitBinder("school")
public void initBinderFormBean2(WebDataBinder binder) {
binder.setFieldDefaultPrefix("school.");
}
4、 List<自定义对象类型>绑定
需要将List的变量绑定到一个对象中才可以,不能直接写在Controller方法的参数中。使用时,“属性名[index].属性名“来命名input的name即可。
5、 Set<自定义对象类型>绑定
同List数据结构绑定相似。
6、 Map<String, 自定义对象类型>绑定。
需要将Map的变量绑定到一个对象中才可以,不能直接写在Controller方法的参数中。使用时,“属性名[key].属性名“来命名input的name即可。
以上数据绑定,均是在form表单数据提交时使用的方法。
Map和List格式的数据,返回数据序列化[5] [6]
@RequestBody
当request header Content-Type为application/json或者application/xml、application/x-www-form-urlencoded,并且request http method为GET或者POST时,方法使用了@RequestBody注解,则springmvc会通过合适的HttpMessageConverter,并根据方法参数类型,对RequestBody中的数据进行解析,并返回参数对象。
此时,json格式即可解析为List或者Map,其中也可以包含自定义对象。
@ResponseBody
如果在方法中使用了@ResponseBody注解,springmvc会根据Request对象中header accept属性(json、xml等)选择适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
后端模板渲染[7]
在springmvc中,可以选择常见的后端模板,进行渲染。如果不使用后端模板渲染的话,前端模板也是可以的。
Javascript模板引擎:artTemplate、juicer、tmpl[8]
1、Jsp
通过如下配置,可以在controller处理完服务逻辑后,将用户请求直接在服务端内进行forwatd到指定的路径上。
配置:
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
<property name="viewClass"
value="org.springframework.web.servlet.view.InternalResourceView"/>
</bean>
2、FreeMarkerViewResolver(VolocityViewResolver)
配置:
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="prefix" value="fm_"/>
<property name="suffix" value=".ftl"/>
<property name="order" value="1"/>
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/freemarker/template"/>
</bean>
解析视图的order顺序为1。
3、在SpringMVC中可以同时定义多个ViewResolver视图解析器,然后它们会组成一个ViewResolver链。当Controller处理器方法返回一个逻辑视图名称后,ViewResolver链将根据其中ViewResolver的优先级(小的优先级高)来进行处理。每个ViewResolver默认都是最大值。
4、springmvc中还可以使用基于协商的视图解析器ContentNegotiatingViewResolver,让springmvc根据MIME类型,选择合适的ViewResolver。[9]
网络资料
官网以及其他个人博客中,有大量关于spring的资料,同时书店中也可以购买到大量spring相关书籍。
自动生成客户端代码
可以通过获取HandlerMapping,以及反射的形式,获取方法参数列表以及返回参数类型,编写程序,完成客户端程序的自动生成。
SpringMVC要是想接收json的数据,需要引入
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
如果想SpringMVC接收xml信息转换为自定义对象,在对象Class上使用注解
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
SpringMVC的messageConvertor可根据contentType(application/xml或者json)进行数据绑定
Jersey
调研目标 |
结果 |
web服务URI映射配置方式难易度 |
使用注解方式,零配置 |
数据绑定是否自动化 |
是(支持各种复杂结构,自定义Bean) |
是否支持Map和List格式的数据绑定 |
是 |
返回数据序列化是否自动化 |
原生为string类型,也支持json自动序列化(xml等其他形式,需手动实现转换,以字符串的形式返回) |
是否支持后端模板渲染 |
否(需手动实现渲染方法,以字符串形式返回) |
网络资料是否充足 |
一般(主要以官网资料最为丰富) |
可否自动生成web服务客户端代码(java等) |
是(可生成wadl。此外框架自带Client,减轻部分客户端编写负担) |
是否可以成为现有服务平台的底层框架 |
否,框架设计思想相差较大,但二者可以合并到一起工作。Jersey只负责开发接口。 |
简介
Jersey作为一个开源的RESTful框架,实现了JAX-RS API[10],并扩展了JAX-RS API,进一步简化了RESTful web service以及service client的开发。
URI映射
Jersey利用JAX-RS标准中的定义,使用注解的方式完成web service的URI映射。
其中@Path定义service的请求路径,方法的@Path会在Controller的@Path的基础上扩展。
@Get、@Post以及@PUT等,定义了方法可以处理哪种http method的请求。
@Produces定义了返回的数据的MIME类型。
@Consumes定义了处理哪种MIME类型的数据。
@Path("/hello")
@Scope("singleton")
public class UserResource {
@GET //标注方法对应的HTTP请求类型
@Path("/{param}") //标注方法的相对路径
@Produces(MediaType.APPLICATION_JSON) //标注返回的MIME媒体类型
public User userInfo(@PathParam("param") String userName) {
User user = new User();
user.setUserId(1);
user.setUserName(userName);
return user;
}
}
数据绑定
1、@PathParam
使用@PathParam可以获取URI中指定规则的参数。
http://localhost/user/jack
@GET
@Path("{username"})
@Produces(MediaType.APPLICATION_JSON)
public User getUser(@PathParam("username") String userName) {
...
}
2、@QueryParam
@QueryParam用于获取GET请求中的查询参数。
http://host:port/user?name=rose&age=25
@GET
@Path("/user")
@Produces("text/plain")
public User getUser(@QueryParam("name") String name,
@QueryParam("age") int age) {
...
}
3、@FormParam
@FormParam,顾名思义,从POST请求的表单参数中获取数据。
@POST
@Consumes("application/x-www-form-urlencoded")
public void post(@FormParam("name") String name) {
// Store the message
}
4、@BeanParam
当请求参数很多时,比如客户端提交一个修改用户的PUT请求,请求中包含很多项用户信息。这时可以用@BeanParam。
@XmlRootElement(name = "user")
public class User {
@PathParam("userName) //我觉得这个应该是写错了,FormParam
private String userName;
@FormParam("name")
private String name;
@FormParam("telephone")
private String telephone;
@FormParam("email")
private String email;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
...
}
5、自定义类型
首先要引入处理json的jar包,在处理MIME为json的数据时,会自动使用匹配的方法处理数据,并返回参数对象。
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.23.1</version>
</dependency>
在方法参数中,直接使用自定义类型即可,会根据自定义类型中的参数名称,自动绑定自定义类型中的数据。同时可以使用数组类型。
Map和List格式的数据绑定
在一个大型的server中,因为参数的多变,参数结构的调整都会因为以上几种方式而遇到问题,这时可以考虑使用@Context 注释,并获取UriInfo实例,进一步获取包含请求参数的Map对象。
@GET
public String get(@Context UriInfo ui) {
MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
MultivaluedMap<String, String> pathParams = ui.getPathParameters();
}
同样还可以通过@Context 注释获取ServletConfig、ServletContext、HttpServletRequest、HttpServletResponse和HttpHeaders等,如下:
@Path("/")
public class Resource {
@Context
HttpServletRequest req;
@Context
ServletConfig servletConfig;
@Context
ServletContext servletContext;
@GET
public String get(@Context HttpHeaders hh) {
MultivaluedMap<String, String> headerParams = hh.getRequestHeaders();
Map<String, Cookie> pathParams = hh.getCookies();
}
}
返回数据序列化
@Produces定义了返回的数据的MIME类型。Jersey会自动将返回的数据转换为对应的格式,无法转换时,会报错。
后端模板渲染
Jsp和freemarker。
在方法中返回Viewable类型的对象,并指定模板名称和数据集合对象。
@Path("foo")
public class Foo {
@GET
public Viewable get() {
return new Viewable("index.foo", "FOO");
}
}
注册模板类
new ResourceConfig()
.register(org.glassfish.jersey.server.mvc.freemarker.FreemarkerMvcFeature.class).register( ... );
网络资料
官网资料最多,其次是个人博客内容,没有相关图书。
自动生成客户端代码
Jersey支持Web Application Description Language (WADL),可以通过/application.wadl路径获取到jersey的wadl信息,通过wadl信息,可以自动生成客户端代码。
Axis2
调研目标 |
结果 |
web服务URI映射配置方式难易度 |
无注解,零配置(服务部署到指定目录) |
数据绑定是否自动化 |
是(支持各种复杂结构,自定义Bean) |
是否支持Map和List格式的数据绑定 |
是 |
返回数据序列化是否自动化 |
是 |
是否支持后端模板渲染 |
否(需手动实现渲染方法,以字符串形式返回) |
网络资料是否充足 |
充足 |
可否自动生成web服务客户端代码(java等) |
可以(axis2支持SOAP协议,可生成wsdl。) |
是否可以成为现有服务平台的底层框架 |
否,框架设计思想相差较大 |
简介
Apache Axis2™ 是一个Web Services / SOAP / WSDL 引擎,可方便的部署web service。主要支持SOAP协议的web service,通过扩展可支持json个数的数据。
根据目前找到的资料发现,axis2处理接收到的数据、返回数据,共要经过3个类4步的处理。
--->messageReceiver(如果有输入数据的话)
--->messageBuilder
--->messageFormatter
--->messageReceiver
需指明不同的messageFormatter和messageBuilde可以处理的contentType类型(xml、json)。
URI映射
部署的每一个web service,其URI为
/类名/方法名
非常的方便,但没有遵循JAX-RS标准。
数据绑定
URI映射采取结构即配置的方式。每一个webservice均有一个配置文件,其中对service的数据处理方式进行了定义。
1、 简单类型数据绑定
直接使用GET或者POST,以key=value&key=value的方式传输参数,service中的参数名同key对应,axis2即可自动完成绑定。
2、 复杂对象绑定
配置好messageReceiver的前提下,按照SOAP或者JSON等方式传输过来的数据,只要数据格式正确,参数名一一对应,即可完成数据绑定。Service的参数个数没有限制。
Map和List格式的数据绑定
如果参数类型为Map、List或者数组,均可自动完成绑定。
返回数据序列化
指定好messageReceiver的类,即可按照配置,将返回数据进行序列化。
要处理json格式的数据时,首先要在axis2的配置中添加以下信息。
<messageFormatter contentType="application/json-impl"
class="org.apache.axis2.json.gson.JsonFormatter" />
<messageBuilder contentType="application/json-impl"
class="org.apache.axis2.json.gson.JsonBuilder" />
然后再service的配置中添加
<messageReceivers>
<messageReceiver mep="http://www.w3.org/ns/wsdl/in-out"
class="org.apache.axis2.json.gson.rpc.JsonRpcMessageReceiver" />
<messageReceiver mep="http://www.w3.org/ns/wsdl/in-only"
class="org.apache.axis2.json.gson.rpc.JsonInOnlyRPCMessageReceiver" />
</messageReceivers>
指定使用Json的RPC处理方式。
使用时注意,发送的POST请求json格式为
{request:[请求参数的对象内容]}
返回的格式为
{response:{返回的对象内容}}
后端模板渲染
没有支持。
可以自己编写渲染接口,以字符串的形式同客户端交互。
网络资料
官网资料,以及代码zip中有大量的sample代码。
自动生成客户端代码
可以生成WSDL,通过WSDL可自动生成客户端代码。
Argo
调研目标 |
结果 |
web服务URI映射配置方式难易度 |
使用注解,零配置(指定扫描的包名即可) |
数据绑定是否自动化 |
否(使用Argo内置的上下文类) |
是否支持Map和List格式的数据绑定 |
否(使用Argo内置的上下文类) |
返回数据序列化是否自动化 |
否(使用Argo内置的上下文类) |
是否支持后端模板渲染 |
支持 |
网络资料是否充足 |
少 |
可否自动生成web服务客户端代码(java等) |
否 |
是否可以成为现有服务平台的底层框架 |
可以,需对jsp页面以及action等的实现进行修改 |
简介
58同城开源的一个MVC框架,遵循JAX-RS标准设置路由映射。
由于Argo是为MVC定制的一款框架,很多都是约定优先,并不需要太多的配置。但对于方法调用时的数据绑定,以及返回时的数据序列化,均依赖于框架本身的接口,没有插件的形式实现自动化的参数绑定和返回数据序列化。
URI映射
支持JAX-RS标准,使用
@Path、@GET、@POST等指明方法映射路径以及可以处理的方法。
数据绑定
无灵活的数据绑定,需使用
BeatContext beat = beat();
ClientContext client = beat.getClient();
client.queryString("company")
获取请求参数。
或者使用路径匹配中的参数。
Map和List格式的数据绑定
未实现。
返回数据序列化
未实现
后端模板渲染
支持velocity引擎。
返回View对象即可指定模板文件。
网络资料
少。
自动生成客户端代码
不能自动生成,同springmvc相似的情况。
Dropwizard
调研目标 |
结果 |
web服务URI映射配置方式难易度 |
使用注解,零配置 |
数据绑定是否自动化 |
是(支持各种复杂结构,自定义Bean) |
是否支持Map和List格式的数据绑定 |
是 |
返回数据序列化是否自动化 |
原生为string类型,也支持json自动序列化(xml等其他形式,需手动实现转换,以字符串的形式返回) |
是否支持后端模板渲染 |
否(需手动实现渲染方法,以字符串形式返回) |
网络资料是否充足 |
一般(主要以官网资料最为丰富) |
可否自动生成web服务客户端代码(java等) |
是(可生成wadl。此外框架自带Client,减轻部分客户端编写负担) |
是否可以成为现有服务平台的底层框架 |
否,框架设计思想相差较大 |
简介
此框架,可以说是各种优秀框架的一个集合体,利用各种框架的优秀特性,比如
Jetty for HTTP
Jackson for JSON
Jersey for REST
完成由底层http服务,数据序列化反序列化,以及restful服务映射的快速实现。
其中服务的定义符合JAX-RS标准(因为使用了jersey作为restful服务实现),服务的参数绑定和返回数据的序列化也可以自动完成(json转换为类对象,对象转化为json)。
此框架同目前的jersey2.*.*非常相似,其使用方式可参考jersey。
Struts2 RESTful
调研目标 |
结果 |
web服务URI映射配置方式难易度 |
使用注解,零配置(指定扫描的包名即可) |
数据绑定是否自动化 |
支持(但是使用复杂) |
是否支持Map和List格式的数据绑定 |
未知 |
返回数据序列化是否自动化 |
支持(服务平台中有使用) |
是否支持后端模板渲染 |
否(使用struts即可,不必使用restful插件) |
网络资料是否充足 |
少(官网资料也很少) |
可否自动生成web服务客户端代码(java等) |
否 |
是否可以成为现有服务平台的底层框架 |
可以,都是基于struts2框架 |
简介
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互.
Struts2 REST Plugin是一款插件,通过修改struts配置,完成REST的添加。
<!--url 后缀设置-->
<constant name="struts.action.extension" value="xhtml,,xml,json,action"/>
<!--设置mapper 针对不同的namespace 设置不同的mapper-->
<constant name="struts.mapper.class"
value="org.apache.struts2.dispatcher.mapper.PrefixBasedActionMapper" />
<constant name="struts.mapper.prefixMapping" value="/rest:rest,:struts"/>
<!--rest 请求默认返回方式-->
<constant name="struts.rest.defaultExtension" value="json" />
<!--rest action所在namespace-->
<constant name="struts.rest.namespace" value="/rest" />
URI映射
在struts.mapper中,有默认的方法映射
l struts.mapper.idParameterName - If set, this value will be the name of the parameter under which the id is stored. The id will then be removed from the action name. Whether or not the method is specified, the mapper will try to truncate the identifier from the url and store it as a parameter.
l struts.mapper.indexMethodName - The method name to call for a GET request with no id parameter. Defaults to index.
l struts.mapper.getMethodName - The method name to call for a GET request with an id parameter. Defaults to show.
l struts.mapper.postMethodName - The method name to call for a POST request with no id parameter. Defaults to create.
l struts.mapper.putMethodName - The method name to call for a PUT request with an id parameter. Defaults to update.
l struts.mapper.deleteMethodName - The method name to call for a DELETE request with an id parameter. Defaults to destroy.
l struts.mapper.editMethodName - The method name to call for a GET request with an id parameter and the edit view specified. Defaults to edit.
l struts.mapper.newMethodName - The method name to call for a GET request with no id parameter and the new view specified. Defaults to editNew.
举例
HTTP method |
URI |
Class.method |
parameters |
GET |
/movie |
Movie.index |
|
POST |
/movie |
Movie.create |
|
PUT |
/movie/Thrillers |
Movie.update |
id="Thrillers" |
DELETE |
/movie/Thrillers |
Movie.destroy |
id="Thrillers" |
GET |
/movie/Thrillers |
Movie.show |
id="Thrillers" |
GET |
/movie/Thrillers/edit |
Movie.edit |
id="Thrillers" |
GET |
/movie/new |
Movie.editNew |
|
数据绑定
在官网未发现相关资料,说明struts rest支持复杂对象绑定方式
Map和List格式的数据绑定
官网未发现相关资料。
返回数据序列化
方法通过返回的String类型的变量,指定一个模板
通过类中的实例变量,可将数据输出到jsp文件中,并渲染。
序列化,需要自定义。
同时REST插件也提供json、xml、html的显示方式,在发送请求时,uri末尾以
.json
.xml
.html
结尾即可,REST插件会自动进行数据序列化。
后端模板渲染
Jsp
网络资料
官网资料很少,博客资料都比较浅显,主要还是翻译官网为主。
自动生成客户端代码
不支持
调研总结
由以上对比发现,如果只是开发REST Web Service,SpringMVC、Jersey、Axis2可以支持复杂的数据绑定形式,返回的数据序列化也很方便,使用这三者开发开放服务平台最为方便,后期维护也简单。
至于根据开放接口的描述信息,生成客户端程序,即使没有自动化的方法,只要可以获得开放接口的类的反射信息,也可以手动编写插件完成客户端程序的生成。
如果考虑到与现有的服务平台,可能只有SpringMVC最为合适,但是底层框架替换的难度还需进一步评估。或者原有服务平台出于维护阶段,不再增加新功能,同时以SpringMVC为底层框架新开工程,在开发开放接口的同时,将原服务平台的功能逐渐迁移到新工程中。
如果可以,根据团队和公司需要,开发一个实现JAX-RS标准的restful框架也可以。
spring的生态环境更好,为了实现更好的扩展性,功能分为了多个层。如果能够理解这么做的原因,推荐使用springmvc。
[1] 本文中所指的web资源、web服务、URI设计风格,以及RESTful框架,均为基于http协议的内容。
[2] REST百度百科 http://baike.baidu.com/view/5798116.htm
[3] Xml和json对比 http://www.cnblogs.com/SanMaoSpace/p/3139186.html
[4] http://www.cnblogs.com/wawlian/archive/2012/11/17/2775435.html
[5] http://blog.csdn.net/kobejayandy/article/details/12690555
[6] Springmvc注解说明及使用 http://www.admin10000.com/document/6436.html
[7] 视图解析详解 http://haohaoxuexi.iteye.com/blog/1770554
[8] Javascript模板引擎性能对比 http://www.07net01.com/program/306389.html
[9] 基于协商的视图解析器 http://blog.csdn.net/z69183787/article/details/41696709
[10] JAX-RS介绍 http://jax-rs-spec.java.net/