2011-06-04 28 views
2

我开发了一个Java中的web服务,作为tomcat上的一个servlet运行,应用程序的参数通过get请求提供给servlet(例如servlet?method = search & query = searchterm123 ),servlet会识别是否定义了方法和查询,如果发生错误,则会返回一个字符串,该字符串将手动包装在通过this.writer.println(answer);硬编码的xml代码中。如果方法正确,实例化一个新类,它将执行搜索,然后返回一个XStream将对象转换为XML的对象,然后再将其发送回客户端,并将println包装到我的xml开销中,然后再次硬编码。String answer ="<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"Java Webservice REST正确设计最佳实践

显然这个工程,也非常有效,但这是远远优雅。我已经非常简短地研究了Apache CXF,还研究了RESTlet或JBOSS RestEasy,后两者我发现对我的要求非常满意。我在CXF上找到的每一个教程总是包含Spring和Maven,然后让我有点困惑。你有什么建议我应该如何将我的肮脏的黑客变成一个漂亮的应用程序?

回答

3

我认为使用JAX-RS框架(如CXF和Resteasy,但也是Jersey)是你的情况。关于序列化XML,也许看看JAXB(例如,也包括在泽西岛中)。它应该有助于自动序列化任何实体结构。

关于这种应用的复杂性:它应该总是取决于您使用的基础设施。如果它只是一个简单的 Java EE服务器,则最好使用该供应商的实现(Jersey for Glassfish,Resteasy for JBoss)。否则,只需使用您熟悉且熟悉的构建系统即可。例如,您可以轻松地用AntIvy替换Maven依赖关系。

3

我可以推荐CXF;我发现使用它的教程非常容易,特别是一旦我咬紧牙关并使用Maven来管理依赖关系(尽管它与CXF和Spring所做的所有事情都是正交的)。

但为了使用CXF,我真的推荐使用Spring。你不必使用Spring的全部; CXF网站上的简单教程使您足以开始学习。如果您已经获得实际已经完成的事情的代码,并从代码中分离出来以解析传入的URL,将响应呈现为XML等,那么尤其如此。这是CXF(通常是JAXB)将为您处理的部分。

为了帮助,这里有一个非常简单的例子(为简洁起见省略了导入)。 我知道它看起来很复杂,但几乎所有的后半部分都是由你写过的东西组成的,然后再不再触摸;当你构建出来处理你真实的代码时,你可以做很多事情,而不必付出必须关注框架代码。 首先,接口定义(包括XML类型的模型):

public interface Foo { 
    @Path("/") @GET @Produces("application/xml"); 
    FooDesc getDescription(@Context UriInfo ui); 
    @Path("{id}") 
    FooItem getFoo(@PathParam("id") String id); 
} 

@Path("/") 
public interface FooItem { 
    @GET @Produces("application/xml") 
    FooItemContents getContents(); 
    @PUT @Consumes("application/xml") 
    void setContents(FooItemContents desc); 
    @DELETE 
    Response delete(); 
} 

// These classes are purely structural holders; no behavior. 

@XmlRootElement @XmlType 
public class FooDesc { 
    @XmlElement 
    public List<URI> foo; 
} 

@XmlRootElement @XmlType 
public class FooItemContents { 
    @XmlElement 
    String bar; 
} 

下,实现类:

public class FooImpl implements Foo { 
    public FooDesc getDescription(UriInfo ui) { 
     FooDesc desc = new FooDesc(); 
     desc.foo = new ArrayList<URI>(); 
     UriBuilder ub = ui.getAbsolutePathBuilder().path("{id}"); 
     for (String id : realGetIdList()) // Hook to your code here! 
      desc.foo.add(ub.build(id)); 
     return desc; 
    } 
    public FooItem getFoo(String id) { 
     final RealFoo r = realGetById(id); // Hook to your code here! 
     return new FooItem() { 
      public FooItemContents getContents() { 
       FooItemContents contents = new FooItemContents(); 
       contents.bar = r.getBar(); // Hook to your code here! 
       return contents; 
      } 
      public void setContents(FooItemContents desc) { 
       r.setBar(desc.bar);  // Hook to your code here! 
      } 
      public Response delete() { 
       r.close();     // Hook to your code here! 
       return Response.noContent().build(); // Return a simple HTTP 204 
      } 
     }; 
    } 
} 

现在,水暖一起在春天水平与WEB-INF/beans.xml

<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"> 

    <!-- Instantiate and connect the service framework --> 
    <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="customerService" address="/"> 
    <jaxrs:serviceBeans> 
     <ref bean="fooBean" /> 
    </jaxrs:serviceBeans> 
    </jaxrs:server> 

    <!-- Instantiate your implementation class --> 
    <bean id="fooBean" class="your.package.FooImpl" /> 
</beans> 

现在,把它作为一个web应用程序,一个web.xml

<web-app> 
    <!-- Magic to make Spring work and build the rest for us --> 
    <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>WEB-INF/beans.xml</param-value> 
    </context-param> 
    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <!-- Make CXF implement the servlet for us --> 
    <servlet> 
    <servlet-name>CXFServlet</servlet-name> 
    <display-name>CXF Servlet</display-name> 
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <!-- You *must* use this servlet mapping or Bad Things Happen. --> 
    <servlet-mapping> 
    <servlet-name>CXFServlet</servlet-name> 
    <url-pattern>/*</url-pattern> 
    </servlet-mapping> 
</web-app> 

现在建立包括在CXF网站上列出的所有库一个WAR,把位在正确的地方(你不需要Maven的这一点,但最终它可以更容易)和部署。这应该是有效的(即,你现在已经足够危险了!)

+0

我已将您的代码添加到我使用cxf原型创建的Maven项目中。不幸的是,我收到了几十个错误,你能添加进口吗?我也想知道例如“RealFoo”在FooImpl.java的第15行,这个类从来没有定义。 – 2011-06-05 12:50:58