最近的项目中,要使用android,ios的客户端访问服务端的资源。因此,服务端的api层选用了rest规范来供客户端远程调用(soap感觉太过于复杂了,语义表达不如rest简洁,而且对于取资源类的服务更加适用于rest,因此选择了rest规范)。
java界的restful的框架主要有cxf,restlet,Jersey,由于restlet的设计理念问题,导致在使用时对代码的侵入性太强,故放弃它。而Jersey这个是sun出的东东,比较简洁,但是好象是不支持soap。说不定哪天我的应用要换成soap规范呢,因此,最终选择了CXF,不过这玩意确实还有些复杂度,主要是和spring关系太过密切了。
折腾了一天时间,才把cxf整合进我的项目工程当中,由于我当前的工程只使用了spring2.0版本(主要是配合mybatis3所用),因此,选用了cxf的2.2.12版本,cxf的新版本都是引用的spring2.5以上的版本,估计会有兼容性的问题。以下是整合时的一些关键步骤说明(带spring的应用方式):
1.web.xml内配置上applicationContext-rest.xml以及添加以下servlet配置
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
2.添加lib包,有cxf-2.2.12.jar,javax.ws.rs.jar,javax.xml.bind.jar(这两个包我是直接从restlet中拿到的),wsdl4j-1.6.2.jar,neethi-2.0.4.jar,缺包的话上http://www.jar114.com/找找看。
3.配置applicationContext-rest.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"
default-lazy-init="false">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxrs:server id="userService" address="/">
<jaxrs:serviceBeans>
<ref bean="userServiceImpl" />
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>
</jaxrs:server>
<bean id="userServiceImpl" class="net.jerrymouse.mmbible.api.rest.service.UserServiceImpl" />
</beans>
4.pojo文件
User.java
package net.jerrymouse.mmbible.api.rest.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "user")
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserMap.java
package net.jerrymouse.mmbible.api.rest.model;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "userMap")
public class UserMap {
Map<String, User> users;
public Map<String, User> getUsers() {
return users;
}
public void setUsers(Map<String, User> users) {
this.users = users;
}
}
UserService.java
package net.jerrymouse.mmbible.api.rest.service;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import net.jerrymouse.mmbible.api.rest.model.User;
import net.jerrymouse.mmbible.api.rest.model.UserMap;
@Path("/common/")
@Produces("application/xml")
public interface UserService {
@GET
@Path("/users/")
public UserMap getUsers();
@GET
@Path("/user/{id}/")
public User getUser(@PathParam("id") String id);
@PUT
@Path("/user/")
public Response updateUser(User user);
@POST
@Path("/user/")
public Response addUser(User user);
@DELETE
@Path("/user/{id}/")
public Response deleteUser(@PathParam("id") String id);
}
UserServiceImpl.java
package net.jerrymouse.mmbible.api.rest.service;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.Response;
import net.jerrymouse.mmbible.api.rest.model.User;
import net.jerrymouse.mmbible.api.rest.model.UserMap;
public class UserServiceImpl implements UserService {
Map<String, User> users = new HashMap<String, User>();
public UserServiceImpl() {
init();
}
public UserMap getUsers() {
System.out.println("----invoking getUser, User id is: XXX ");
UserMap u = new UserMap();
u.setUsers(users);
return u;
}
public User getUser(String id) {
System.out.println("----invoking getUser, User id is: " + id);
User u = users.get(id);
return u;
}
public Response updateUser(User user) {
System.out.println("----invoking updateUser, User name is: "
+ user.getUsername());
User u = users.get(user.getUsername());
Response r;
if (u != null) {
users.put(user.getUsername(), user);
r = Response.ok().build();
} else {
r = Response.notModified().build();
}
return r;
}
public Response addUser(User user) {
System.out.println("----invoking addUser, User name is: " + user.getUsername());
users.put(user.getUsername(), user);
return Response.ok(user).build();
}
public Response deleteUser(String id) {
System.out.println("----invoking deleteUser, User id is: " + id);
User u = users.get(id);
Response r;
if (u != null) {
r = Response.ok().build();
users.remove(u);
} else {
r = Response.notModified().build();
}
return r;
}
private final void init() {
User user = new User();
user.setUsername("admin");
user.setPassword("11");
users.put(user.getUsername(), user);
}
}
代码写好了,访问方式:
http://127.0.0.1:8080/api/common/users
http://127.0.0.1:8080/api/common/user/admin
只详细测试了GET的调用过程。
以上是使用spring的方式,要是不想用spring,可以参考:
http://liuqiang5151.iteye.com/blog/840496,官网也有篇英文的介绍如何去掉spring的方式,和以上链接是同一原理。
主要参考资料:
http://dhruba.name/2008/12/08/rest-service-example-using-cxf-22-jax-rs-10-jaxb-and-spring/
http://www.ibm.com/developerworks/cn/education/xml/x-restatompp/index.html
若想用restlet,可以参考:
http://ajaxcn.iteye.com/blog/414822
http://ajaxcn.iteye.com/blog/414911
最新评论
19 周 2 天之前
20 周 6 天之前
21 周 2 天之前
23 周 3 天之前
26 周 2 天之前
31 周 6 天之前
42 周 6 天之前
43 周 4 天之前
1 年 1 周之前
1 年 12 周之前