`
m635674608
  • 浏览: 5055286 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java tjws

    博客分类:
  • java
 
阅读更多

RESTEasy除了能够运行于标准Web服务器(如Tomcat),或是与J2EE容器(如JBoss AS)整合之外,还可以嵌入式的方式运行,本文通过一些代码实例来对这些功能和RESTEasy中相关的classes进行说明。

TJWS
首先,我们需要理解,RESTEasy使用TJWS作为嵌入式RESTFul WebService服务的容器。TJWS是一个开源的Servlet容器,它相当轻便小巧,占用资源少,启动速度快,因此做为嵌入式容器非常适合。在 RESTEasy中,已经自包含了一个tjws服务器,如果签出RESTEasy的代码则可以看到它位于代码中的tjws目录:

Bash代码  收藏代码
  1. liweinan@smart:~/projs/resteasy/jaxrs$ ls -l | grep tjws  
  2. drwxr-xr-x   7 liweinan  staff    238 Sep  5 22:37 tjws  



基于TJWS这个容器,RESTEasy为我们提供了TJWSEmbeddedJaxrsServer,开发人员可以很方便地使用它来启动一个内嵌于代码之中的JAX-RS服务。下面我们动手实际做一个例子试试看:

HelloWorldService
首先我们来创建一个最简单的RESTFul WebService:

Java代码  收藏代码
  1. import javax.ws.rs.GET;  
  2. import javax.ws.rs.Path;  
  3. import javax.ws.rs.Produces;  
  4.   
  5. @Path("/helloworld")  
  6. public interface HelloWorldService {  
  7.   
  8.     @GET  
  9.     @Produces("text/plain")  
  10.     public String printHelloWorld();  
  11. }  



以下是它的实现类:

Java代码  收藏代码
  1. public class HelloWorldServiceImpl implements HelloWorldService {  
  2.     public static final String HELLO_WORLD = "Hello, world!";  
  3.   
  4.     public String printHelloWorld() {  
  5.         return HELLO_WORLD;  
  6.     }  
  7. }  



很简单的一个WebService,不需做太多说明。接下来的重点是如何使用TJWSEmbeddedJaxrsServer来将这个WebService启动起来:

TJWSEmbeddedJaxrsServer
我们可以通过JUnit单元测试的形式来实现这个例子:

Java代码  收藏代码
  1. import org.jboss.resteasy.plugins.server.tjws.TJWSEmbeddedJaxrsServer;  
  2. import org.junit.After;  
  3. import org.junit.Before;  
  4. import org.junit.Test;  
  5.   
  6. import java.io.BufferedReader;  
  7. import java.io.IOException;  
  8. import java.io.InputStreamReader;  
  9. import java.net.HttpURLConnection;  
  10. import java.net.URL;  
  11.   
  12. import static org.junit.Assert.assertEquals;  
  13.   
  14. public class TestTJWSEmbeddedJAXRSServer {  
  15.   
  16.     private static TJWSEmbeddedJaxrsServer tjws;  
  17.   
  18.     @Before  
  19.     public void setUp() {  
  20.         tjws = new TJWSEmbeddedJaxrsServer();  
  21.         tjws.setPort(8081);  
  22.         tjws.getDeployment().getActualResourceClasses().add(HelloWorldServiceImpl.class);  
  23.         tjws.start();  
  24.     }  
  25.   
  26.     @After  
  27.     public void tearDown() {  
  28.         tjws.stop();  
  29.     }  
  30.   
  31.     @Test  
  32.     public void testEmbeddedJAXRSServer() throws IOException {  
  33.         URL url = new URL("http://127.0.0.1:8081/helloworld");  
  34.         HttpURLConnection connection = (HttpURLConnection) url.openConnection();  
  35.         connection.setRequestMethod("GET");  
  36.         connection.setRequestProperty("Content-Type""text/plain");  
  37.         connection.setDoOutput(true);  
  38.         connection.setInstanceFollowRedirects(false);  
  39.         connection.setConnectTimeout(1000);  
  40.   
  41.         BufferedReader ir = new BufferedReader(new InputStreamReader(connection.getInputStream()));  
  42.   
  43.         assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());  
  44.         assertEquals("Hello, world!", ir.readLine());  
  45.         ir.close();  
  46.         connection.disconnect();  
  47.   
  48.     }  
  49.   
  50. }  



从上面的代码中,我们可以看到,在setUp()方法中,我们将HelloWorldServiceImpl这个WebService添加进了 TJWSEmbeddedJaxrsServer当中并启动了这个server,同时设定的服务端口为8081。值得说明的是这行代码:

Java代码  收藏代码
  1. tjws.getDeployment().getActualResourceClasses().add(HelloWorldServiceImpl.class);  



我们是以perRequestResource的形式将HelloWorldServiceImpl服务进行注册,这一点从org.jboss.resteasy.spi.ResteasyDeployment的源代码中可以看出来:

Java代码  收藏代码
  1. ...  
  2. registry.addPerRequestResource(actualResourceClass);  
  3. ...  



因此,我们的HelloWorldServiceImpl,将在每次客户端请求服务时被RESTEasy进行实例化,服务处理完成后销毁。如果我们想以singleton方式来添加我们的WebService,可以使用getResourceFactories()方法:

Java代码  收藏代码
  1. tjws.getDeployment().getResourceFactories().add(HelloWorldServiceImpl.class);  



这种情况下我们必须自己来保证HelloWorldServiceImpl是线程安全的。如果你不了解我这里说的singleton模式,可参考 蓝点上这篇 "RESTEasy的入门文章":http://bluedash.net/spaces/RESTEasy ,理解了RESTEasyr的基本使用方法后,再回来看本篇文章。

我们继续看这个单元测试的源代码,在setUp()方法中,我们进行了服务注册及参数的配置之后,便启动了这个内嵌的WebService服务:

Java代码  收藏代码
  1. tjws.start();  



接下来,在主测试程序中,我们通过使用最基本的HTTP协议来调用WebService服务,并查看返回值与期望是否相附,代码很明白,没有需要特别说明的地方。

最后,在tearDown() 方法中,我们关闭了WebService服务:

Java代码  收藏代码
  1. tjws.stop();  



这是测试完成后必要的清理工作。

InMemoryClientExecutor
如果我们不需要对外提供WebService服务,而只是会在自己的项目代码中,以编码的形式来调用自己的WebService,RESTEasy还提供了更为轻量级的InMemoryClientExecutor, 下面是一个例子:

Java代码  收藏代码
  1. import org.jboss.resteasy.client.ClientRequest;  
  2. import org.jboss.resteasy.client.core.executors.InMemoryClientExecutor;  
  3. import org.junit.Test;  
  4.   
  5. import static org.junit.Assert.assertEquals;  
  6.   
  7. public class TestInMemoryClientExecutor {  
  8.   
  9.     @Test  
  10.     public void testHelloWorld() throws Exception {  
  11.         InMemoryClientExecutor executor = new InMemoryClientExecutor();  
  12.         executor.getDispatcher().getRegistry().addPerRequestResource(HelloWorldServiceImpl.class);  
  13.         ClientRequest request = new ClientRequest("/helloworld", executor);  
  14.         assertEquals(HelloWorldServiceImpl.HELLO_WORLD, request.getTarget(String.class));  
  15.     }  
  16. }  



一般是在RESTEasy自身的测试代码中多见这个InMemoryClientExecutor的使用,在一般的应用编码情况下,可能InMemoryClientExecutor用到的场合并不会太多。

TJWSServletContainer
在RESTEasy的单元测试代码中,提供了一个很方便的TJWSServletContainer类,它对TJWSEmbeddedJaxrsServer进行了封装,我们也可以使用这个来实现我们的嵌入式WebService服务:

Java代码  收藏代码
  1. import org.jboss.resteasy.client.ProxyFactory;  
  2. import org.jboss.resteasy.plugins.providers.RegisterBuiltin;  
  3. import org.jboss.resteasy.spi.ResteasyDeployment;  
  4. import org.jboss.resteasy.spi.ResteasyProviderFactory;  
  5. import org.jboss.resteasy.test.TJWSServletContainer;  
  6. import org.junit.AfterClass;  
  7. import org.junit.BeforeClass;  
  8. import org.junit.Test;  
  9.   
  10. import static org.junit.Assert.assertEquals;  
  11.   
  12. public class TestTJWSServletContainer {  
  13.   
  14.     @BeforeClass  
  15.     public static void setUp() throws Exception {  
  16.   
  17.         ResteasyDeployment deployment = TJWSServletContainer.start();  
  18.         deployment.getRegistry().addPerRequestResource(HelloWorldServiceImpl.class);  
  19.     }  
  20.   
  21.     @AfterClass  
  22.     public static void stop() throws Exception {  
  23.         TJWSServletContainer.stop();  
  24.     }  
  25.   
  26.   
  27.     @Test  
  28.     public void testIt() throws Exception {  
  29.         RegisterBuiltin.register(ResteasyProviderFactory.getInstance());  
  30.         HelloWorldService client = ProxyFactory.create(HelloWorldService.class"http://127.0.0.1:8081");  
  31.         assertEquals("Hello, world!", client.printHelloWorld());  
  32.   
  33.     }  
  34. }  



这个例子在本质上和直接使用TJWSEmbeddedJaxrsServer没有任何区别(实际上是有一点区别,有兴趣的读者可以参考下一节深入 讨论的内容)。另外,在这个单元测试的主测试功能testIt当中,我们并没有使用最直接的HTTP的调用方式,而是利用了RESTEasy客户端的方式 来调用了WebService,可以看到,和第一个例子中那个单元测试相比,少写了多少代码,所以使用RESTEasy客户端来调用RESTEasy的 WebService应该是最省事的。

深入讨论
如果对RESTEasy的源代码实现没兴趣,本节内容可以无视。我们要讨论第一个例子(针对TJWSEmbeddedJaxrsServer)和第三个例子(针对TJWSServletContainer)中的一处代码上的区别。在第一个例子中,我们注册服务的代码为:

Java代码  收藏代码
  1. tjws.getDeployment().getActualResourceClasses().add(HelloWorldServiceImpl.class);  



而在第三个例子中,我们使用的方法为:

Java代码  收藏代码
  1. deployment.getRegistry().addPerRequestResource(HelloWorldServiceImpl.class);  



实际上我们同为使用ResteasyDeploy这个类来注册我们的Service,为什么两个代码中使用的方法不同呢?

仔细看下我们会发现,两个方法所处的上下文环境不同。再看下第一个:

Java代码  收藏代码
  1. ...  
  2. tjws.getDeployment().getActualResourceClasses().add(HelloWorldServiceImpl.class);  
  3. tjws.start();  
  4. ...  



我们是在start()之前来注册服务。而第三个例子中:

Java代码  收藏代码
  1. ...  
  2. ResteasyDeployment deployment = TJWSServletContainer.start();  
  3. deployment.getRegistry().addPerRequestResource(HelloWorldServiceImpl.class);  
  4. ...  



我们是在start()之后来注册服务。这就是两者使用不同方法的重要区别,看下ResteasyDeployment这个RESTEasy中的 核心类,我们会发现,它是在start()中进行registry的加载工作,并调用registration()方法将我们在 getActualResourceClasses中添加的服务注册进Registry的:

Java代码  收藏代码
  1. package org.jboss.resteasy.spi;  
  2. ...  
  3. public class ResteasyDeployment {  
  4.    public void start() {  
  5.       registry = dispatcher.getRegistry();  
  6.       ...  
  7.       registration();  
  8.       ...  
  9.    }  
  10.   
  11.    ...  
  12.    public void registration() {  
  13.       ...  
  14.       if (resourceClasses != null)  
  15.       {  
  16.          for (String resource : resourceClasses)  
  17.          {  
  18.             Class clazz = null;  
  19.             try  
  20.             {  
  21.                clazz = Thread.currentThread().getContextClassLoader().loadClass(resource.trim());  
  22.             }  
  23.             catch (ClassNotFoundException e)  
  24.             {  
  25.                throw new RuntimeException(e);  
  26.             }  
  27.             registry.addPerRequestResource(clazz);  
  28.          }  
  29.       }  
  30.    }  
  31. ...  
  32. }  




了解了细节之后,我们便知道第一个例子和第三个例子当中这一差异的原因了。在这里要特别说明一下,我们在使用RESTEasy的时候,应该使用第 一种方式,因为这是写在RESTEasy官方文档中的标准使用及调用方法。第三个例子中介绍的先start(),再添加服务的调用方法,并没有写在 RESTEasy的文档里,是一种"非标准"的使用,了解即可。

有关样例代码
我将本文中使用的代码放在了github上面,有兴趣的读者可以自己下载代码玩玩看:

Html代码  收藏代码
  1. https://github.com/liweinan/try-resteasy  



使用这个git命令签出代码:

Bash代码  收藏代码
  1. git clone git://github.com/liweinan/try-resteasy.git  



代码签出后可以用maven命令来执行本文中的代码:

Bash代码  收藏代码
  1. mvn test 

http://weli.iteye.com/blog/1299497

分享到:
评论

相关推荐

    JAVA源码JavaHTTP服务器TJWS

    JAVA源码JavaHTTP服务器TJWS

    Java HTTP服务器 TJWS

    TJWS以其简单易用、源码开放的特点,为Java开发者提供了一个快速测试和部署Java Web应用的平台。 1. **HTTP协议基础** HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从Web服务器传输超文本到...

    java资源JavaHTTP服务器TJWS

    java资源Java HTTP服务器 TJWS提取方式是百度网盘分享地址

    Java HTTP服务器 TJWS源码

    TJWS,全称为Tiny Java Web Server,因其小巧且易于理解的源码而受到开发者们的欢迎,尤其适合初学者研究和实践。 在Java HTTP服务器TJWS源码中,我们可以学习到以下几个重要的知识点: 1. **Java Socket编程**:...

    java源码:Java HTTP服务器 TJWS.zip

    Java源码:Java HTTP服务器TJWS是一个经典的开源项目,它提供了一个轻量级的HTTP服务器实现,使得开发者能够在Java环境中快速搭建Web服务。TJWS全称为Tiny Java Web Server,其设计理念是简单、小巧且高效,对于学习...

    基于java的开发源码-HTTP服务器 TJWS.zip

    基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于java的开发源码-HTTP服务器 TJWS.zip 基于...

    Java HTTP服务器 TJWS.7z

    Java HTTP服务器TJWS是一个轻量级的开源项目,它允许开发者在Java环境中快速搭建一个简单的HTTP服务器。这个服务器能够处理HTTP请求,并返回相应的HTTP响应,对于学习网络编程、Java服务器开发以及快速测试Web应用...

    基于java的HTTP服务器 TJWS.zip

    "java"标签表示TJWS是用Java语言编写的,这暗示了它具有跨平台性,能够在任何支持Java的系统上运行,包括Windows、Linux、Mac OS等。 【核心知识点】 1. **Java语言基础**:理解TJWS之前,需要熟悉Java基础语法,...

    基于Java的HTTP服务器 TJWS.zip

    "TJWS"(Tiny Java Web Server)就是一个小巧且易于理解的Java HTTP服务器实现,适合初学者和有经验的开发者学习和研究。 **HTTP协议** HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从Web...

    基于Java的源码-HTTP服务器 TJWS.zip

    【标题】"基于Java的源码-HTTP服务器 TJWS.zip" 涉及的主要知识点是Java编程语言、网络协议中的HTTP以及服务器开发。TJWS(Tiny Java Web Server)是一个小型、快速且易于理解的开源Java HTTP服务器,适用于学习和...

    基于Java的实例开发源码-HTTP服务器 TJWS.zip

    TJWS(Tiny Java Web Server)是一个小型、轻量级的Java Web服务器,适用于学习和快速开发测试。它允许开发者在本地运行Web应用,无需复杂的服务器环境。 【描述】"基于Java的实例开发源码-HTTP服务器 TJWS.zip" ...

    基于Java的实例源码-HTTP服务器 TJWS.zip

    TJWS(Tiny Java Web Server)是一个轻量级的Java Web服务器,用于演示和学习如何在Java环境中构建Web服务。 【描述解析】 描述部分 "基于Java的实例源码-HTTP服务器 TJWS.zip" 明确指出这是一个Java编程的实践项目...

    TJWS2:小型Java Web和App服务器第二代

    【TJWS2:小型Java Web和App服务器第二代】是一个专为轻量级应用设计的服务器平台,它是第一代TJWS的升级版。TJWS(Tomcat Junior Web Server)作为一个开源项目,旨在提供一个高效、简洁的Java Web应用程序和应用...

    小程序 Java HTTP服务器 TJWS(源码).zip

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    java.net.SocketException Connection reset 解决方法

    "java.net.SocketException Connection reset 解决方法" 在 Java 编程中,SocketException 是一种常见的异常,特别是在网络编程中。Conexion reset by peer 是一种特殊的 SocketException,它发生在客户端和服务器...

    java开源包4

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包101

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包8

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包10

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包6

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

Global site tag (gtag.js) - Google Analytics