本章节在于记录研究某个项目时遇到的restful架构技术jersey框架,这里以自己写的一个简单例子作为切入jersey的参考。本次使用的架构是jersey+guice,jersey作为rest服务框架,guice作为di框架。使用内嵌jetty作为应用容器,舍弃web.xml配置。
进入正题:
一、maven依赖:
以下所列的依赖并非最小集。
-
<dependencies>
-
<dependency>
-
<groupId>org.eclipse.jetty</groupId>
-
<artifactId>jetty-server</artifactId>
-
<version>8.1.19.v20160209</version>
-
</dependency>
-
<dependency>
-
<groupId>org.eclipse.jetty</groupId>
-
<artifactId>jetty-security</artifactId>
-
<version>8.1.19.v20160209</version>
-
</dependency>
-
<dependency>
-
<groupId>org.eclipse.jetty</groupId>
-
<artifactId>jetty-servlet</artifactId>
-
<version>8.1.19.v20160209</version>
-
</dependency>
-
<dependency>
-
<groupId>org.eclipse.jetty</groupId>
-
<artifactId>jetty-webapp</artifactId>
-
<version>8.1.19.v20160209</version>
-
</dependency>
-
<dependency>
-
<groupId>javax.servlet</groupId>
-
<artifactId>javax.servlet-api</artifactId>
-
<version>3.1.0</version>
-
<scope>provided</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.codehaus.jackson</groupId>
-
<artifactId>jackson-core-asl</artifactId>
-
<version>1.9.9</version>
-
</dependency>
-
<dependency>
-
<groupId>org.codehaus.jackson</groupId>
-
<artifactId>jackson-jaxrs</artifactId>
-
<version>1.9.9</version>
-
</dependency>
-
<dependency>
-
<groupId>org.codehaus.jackson</groupId>
-
<artifactId>jackson-xc</artifactId>
-
<version>1.9.9</version>
-
</dependency>
-
<dependency>
-
<groupId>org.codehaus.jackson</groupId>
-
<artifactId>jackson-mapper-asl</artifactId>
-
<version>1.9.13</version>
-
</dependency>
-
<dependency>
-
<groupId>org.glassfish.jersey.containers</groupId>
-
<artifactId>jersey-container-servlet</artifactId>
-
<version>2.19</version>
-
</dependency>
-
<dependency>
-
<groupId>org.glassfish.jersey.core</groupId>
-
<artifactId>jersey-client</artifactId>
-
<version>2.19</version>
-
</dependency>
-
<dependency>
-
<groupId>org.glassfish.jersey.containers</groupId>
-
<artifactId>jersey-container-jetty-servlet</artifactId>
-
<version>2.19</version>
-
</dependency>
-
-
<dependency>
-
<groupId>com.squarespace.jersey2-guice</groupId>
-
<artifactId>jersey2-guice</artifactId>
-
<version>0.10</version>
-
</dependency>
-
<dependency>
-
<groupId>com.google.inject.extensions</groupId>
-
<artifactId>guice-servlet</artifactId>
-
<version>4.0</version>
-
</dependency>
-
<dependency>
-
<groupId>com.google.inject</groupId>
-
<artifactId>guice</artifactId>
-
<version>4.0</version>
-
</dependency>
-
<dependency>
-
<groupId>com.google.inject.extensions</groupId>
-
<artifactId>guice-assistedinject</artifactId>
-
<version>4.0</version>
-
</dependency>
-
<dependency>
-
<groupId>com.google.inject.extensions</groupId>
-
<artifactId>guice-persist</artifactId>
-
<version>4.0</version>
-
</dependency>
-
<dependency>
-
<groupId>com.alibaba</groupId>
-
<artifactId>fastjson</artifactId>
-
<version>1.2.21</version>
-
</dependency>
-
<dependency>
-
<groupId>commons-logging</groupId>
-
<artifactId>commons-logging</artifactId>
-
<version>1.2</version>
-
</dependency>
-
<dependency>
-
<groupId>org.slf4j</groupId>
-
<artifactId>slf4j-api</artifactId>
-
<version>1.7.2</version>
-
</dependency>
-
<dependency>
-
<groupId>org.slf4j</groupId>
-
<artifactId>slf4j-log4j12</artifactId>
-
<version>1.7.2</version>
-
</dependency>
-
</dependencies>
二、内嵌jetty容器及配置
-
import java.util.Collections;
-
import java.util.List;
-
import org.eclipse.jetty.server.Server;
-
import org.eclipse.jetty.server.nio.SelectChannelConnector;
-
import org.eclipse.jetty.servlet.ServletHolder;
-
import org.eclipse.jetty.util.resource.Resource;
-
import org.eclipse.jetty.util.thread.QueuedThreadPool;
-
import org.eclipse.jetty.webapp.WebAppContext;
-
import org.glassfish.jersey.servlet.ServletContainer;
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
import com.google.inject.Module;
-
import com.google.inject.servlet.GuiceFilter;
-
import com.newland.jerseyTest.moudle.MyModule;
-
import com.squarespace.jersey2.guice.JerseyGuiceServletContextListener;
-
public class JerseyTestServer {
-
private static Logger LOG = LoggerFactory.getLogger(JerseyTestServer.class);
-
private Server server = null;
-
public void run() throws Exception{
-
LOG.debug("starting......................");
-
server = new Server();
-
WebAppContext app = new WebAppContext();
-
app.setContextPath("/");
-
app.setBaseResource(Resource.newClassPathResource(""));
-
JerseyGuiceServletContextListener jgscl = new JerseyGuiceServletContextListener() {
-
@Override
-
protected List<? extends Module> modules() {
-
return Collections.singletonList(new MyModule());
-
}
-
};
-
app.addEventListener(jgscl);//配置监听器
-
app.addFilter(GuiceFilter.class, "/*", null);//配置过滤器
-
ServletHolder sh = new ServletHolder(ServletContainer.class);
-
sh.setInitParameter("jersey.config.server.provider.packages", "com.newland.jerseyTest.controller");//resource资源包路径
-
sh.setInitOrder(1);
-
app.addServlet(sh, "/my/v1/*");//配置servlet,servlet的前缀
-
server.setHandler(app);//启用web配置
-
server.setThreadPool(new QueuedThreadPool(25));
-
SelectChannelConnector conn = new SelectChannelConnector();
-
conn.setPort(8088);//服务端口
-
conn.setMaxIdleTime(600000);
-
server.addConnector(conn);
-
server.setSendServerVersion(false);
-
server.setStopAtShutdown(true);
-
app.start();
-
server.start();//服务启动
-
}
-
public void stop(){
-
try {
-
server.stop();
-
} catch (Exception e) {
-
LOG.error("stop failed.", e);
-
}
-
}
-
public static void main(String[] args) {
-
JerseyTestServer server = null;
-
try{
-
server = new JerseyTestServer();
-
if(server != null){
-
server.run();
-
}
-
} catch(Exception e){
-
LOG.error("Start failed.", e);
-
if(server != null)server.stop();
-
}
-
}
-
}
三、自定义module
guice创建injector(guice注入工具)需要一个module参数,该module是告诉guice如何在注入时注入哪个类的实例。
-
import com.google.inject.AbstractModule;
-
import com.google.inject.servlet.ServletModule;
-
import com.newland.jerseyTest.service.MyService;
-
import com.newland.jerseyTest.service.impl.MyServiceImpl;
-
public class MyModule extends AbstractModule {
-
@Override
-
protected void configure() {
-
install(new ServletModule(){
-
protected void configureServlets(){
-
bind(MyService.class).to(MyServiceImpl.class);//在需要注入MyService对象时,guice会据此注入MyServiceImpl实例
-
}
-
});
-
}
-
}
四、reset接口
这里可以体现reset风格的特点,参数可以在请求的uri中传递。我这里的接口只是用来接收请求和返回响应,业务处理交个service层处理,类似spring的controller或struts的action层。
-
import java.util.HashMap;
-
import java.util.Map;
-
import javax.ws.rs.GET;
-
import javax.ws.rs.Path;
-
import javax.ws.rs.PathParam;
-
import javax.ws.rs.Produces;
-
import javax.ws.rs.core.Context;
-
import javax.ws.rs.core.HttpHeaders;
-
import javax.ws.rs.core.MediaType;
-
import javax.ws.rs.core.Response;
-
import javax.ws.rs.core.UriInfo;
-
import com.alibaba.fastjson.JSON;
-
import com.google.inject.Inject;
-
import com.newland.jerseyTest.service.MyService;
-
@Path("/test")
-
public class MyController{
-
@Inject
-
private MyService myService;
-
@GET
-
@Path("{userName}")
-
@Produces(MediaType.APPLICATION_JSON)
-
public Response giveAnswer(@Context HttpHeaders headers, @Context UriInfo uri,
-
@PathParam("userName") String userName){
-
String ret = myService.returnSomething(userName);
-
Map<String, String> answer = new HashMap<String, String>();
-
answer.put("message", ret);
-
return Response.status(200).entity(JSON.toJSONString(answer)).build();
-
}
-
}
五、业务处理
业务处理接口
-
public interface MyService {
-
public String returnSomething(String userName);
-
}
业务处理实现
-
import com.newland.jerseyTest.service.MyService;
-
public class MyServiceImpl implements MyService {
-
@Override
-
public String returnSomething(String userName) {
-
return "Hello " + userName + " !!!";
-
}
-
}
六、测试
ok,一个使用jersey实现的rest服务就完成了。