2011-06-04 34 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