2013-07-30 14 views
14

Tak więc próbuję osadzić pomost w mojej aplikacji sieciowej, więc jeśli zapakuję ją jako słoik, ktoś może po prostu uruchomić plik JAR bez martwienia się o konfigurację serwera. Mam jednak pewne problemy z konfiguracją mojej głównej klasy, aby pomost mógł uzyskać dostęp do moich klas zasobów. Przyjrzałem się tutorialom, ale nie dali mi dokładnie tego, czego szukam. To jest to, co do tej pory miałem.Jak osadzić Jetty i Jersey w mojej aplikacji Java

package pojo; 

import org.eclipse.jetty.server.Server; 
import org.eclipse.jetty.servlet.DefaultServlet; 
import org.eclipse.jetty.servlet.ServletContextHandler; 
import org.eclipse.jetty.servlet.ServletHolder; 

public class Main { 

    public static void main(String[] args) throws Exception { 
     Server server = new Server(8080); 
     ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS); 
     context.setContextPath("/"); 
     ServletHolder h = new ServletHolder(new DefaultServlet()); 
     h.setInitParameter("javax.ws.rs.Application","resources.DBCollection"); 
     context.addServlet(h, "/*"); 
     server.setHandler(context); 
     server.start(); 
     server.join(); 
    } 
} 

I próbuję mapować go do tej klasy:

package resources; 


import java.util.ArrayList; 
import java.util.List; 

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.MediaType; 
import javax.ws.rs.core.Request; 
import javax.ws.rs.core.UriInfo; 

import pojo.Party; 

@Path("/parties") 
public class DBCollection { 

    @Context 
    UriInfo url; 

    @Context 
    Request request; 

    String name; 

    @GET 
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) 
    public List<Party> getAllParties() throws Exception 
    { 
     List<Party> list = new ArrayList<Party>(); 
     list.addAll(DBConnection.getPartyCollection().values()); 
     return list; 
    } 

    @GET 
    @Path("count") 
    @Produces(MediaType.TEXT_PLAIN) 
    public String getPartyCount() throws Exception 
    { 
     return String.valueOf(DBConnection.getPartyCollection().size()); 
    } 

    @Path("{party}") 
    public DBResource getParty(@PathParam("party")String party) 
    { 
     return new DBResource(url,request,party); 
    } 
} 

Oto mój plik POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>PartyAPI</groupId> 
    <artifactId>PartyAPIMaven</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 
    <dependencies> 
     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
      <version>5.1.6</version> 
     </dependency> 
     <dependency> 
      <groupId>com.codahale.metrics</groupId> 
      <artifactId>metrics-core</artifactId> 
      <version>3.0.1</version> 
     </dependency> 
     <dependency> 
      <groupId>com.sun.jersey</groupId> 
      <artifactId>jersey-server</artifactId> 
      <version>1.17.1</version> 
     </dependency> 

     <dependency> 
      <groupId>org.eclipse.jetty</groupId> 
      <artifactId>jetty-server</artifactId> 
      <version>9.0.0.RC0</version> 
      <scope>compile</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.eclipse.jetty</groupId> 
      <artifactId>jetty-servlet</artifactId> 
      <version>9.0.0.RC0</version> 
      <scope>compile</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.eclipse.jetty</groupId> 
      <artifactId>jetty-servlets</artifactId> 
      <version>9.0.0.RC0</version> 
      <scope>compile</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.eclipse.persistence</groupId> 
      <artifactId>eclipselink</artifactId> 
      <version>2.6.0-SNAPSHOT</version> 
     </dependency> 

    </dependencies> 
    <repositories> 
     <repository> 
      <id>oss.sonatype.org</id> 
      <name>OSS Sonatype Staging</name> 
      <url>https://oss.sonatype.org/content/groups/staging</url> 
     </repository> 
    </repositories> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-shade-plugin</artifactId> 
       <version>1.6</version> 
       <configuration> 
        <createDependencyReducedPom>true</createDependencyReducedPom> 
        <filters> 
         <filter> 
          <artifact>*:*</artifact> 
          <excludes> 
           <exclude>META-INF/*.SF</exclude> 
           <exclude>META-INF/*.DSA</exclude> 
           <exclude>META-INF/*.RSA</exclude> 
          </excludes> 
         </filter> 
        </filters> 
       </configuration> 
       <executions> 
        <execution> 
         <phase>package</phase> 
         <goals> 
          <goal>shade</goal> 
         </goals> 
         <configuration> 
          <transformers> 
           <transformer 
            implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> 
           <transformer 
            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
            <manifestEntries> 
             <Main-Class>com.resteasy.Star.Main</Main-Class> 

            </manifestEntries> 

           </transformer> 
          </transformers> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

Odpowiedz

20

Kilka rzeczy.

  1. Jetty 9.0.0.RC0 jest stary, nie-jeszcze stabilny, release candidate, należy rozważyć aktualizację do stabilnej wersji ostatecznej, takich jak 9.0.4.v20130625
  2. Trzeba coś, co będzie łączyć tej klasy RS w Jax aplet apletu. Zwykle odbywa się za pośrednictwem serwletu lub inicjalizacji z wybraną biblioteką. (W tobie rozróżniana Jersey)

W przykładzie, trzeba tylko tylko konfiguracja DefaultServlet służyć pliki statyczne, nic nie zostało skonfigurowane do korzystania z obiektu DBCollection.

W przypadku Jersey należy skonfigurować org.glassfish.jersey.servlet.ServletContainer i skonfigurować odwzorowania serwletów w wybranym kontekście.

Przykład:

package com.example; 

import org.eclipse.jetty.server.Server; 
import org.eclipse.jetty.servlet.DefaultServlet; 
import org.eclipse.jetty.servlet.ServletContextHandler; 
import org.eclipse.jetty.servlet.ServletHolder; 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     Server server = new Server(8080); 

     ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS); 
     context.setContextPath("/"); 
     server.setHandler(context); 

     ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/webapi/*"); 
     jerseyServlet.setInitOrder(1); 
     jerseyServlet.setInitParameter("jersey.config.server.provider.packages","com.example"); 

     ServletHolder staticServlet = context.addServlet(DefaultServlet.class,"/*"); 
     staticServlet.setInitParameter("resourceBase","src/main/webapp"); 
     staticServlet.setInitParameter("pathInfoOnly","true"); 

     try 
     { 
      server.start(); 
      server.join(); 
     } 
     catch (Throwable t) 
     { 
      t.printStackTrace(System.err); 
     } 
    } 
} 

Ten przykład dodaje ServletContainer że Jersey zapewnia do ServletContextHandler że Jetty używa patrzeć co robić w oparciu o wniosek przychodzącego. Następnie dodaje DefaultServlet, aby obsłużyć wszystkie żądania treści, których Jersey nie obsługuje (takie jak zawartość statyczna).

+0

Kiedy więc wprowadzam localhost: 8111/webapi/parties otrzymuję błąd 500 (Uwaga: zmieniłem port na 8111, ponieważ otrzymałem wyjątek NetBind), jak to naprawić (nie wydrukowano żadnego stosu strace). Ponadto, nie mogłem znaleźć javadoców, czy mógłbyś wyjaśnić, co robi setInitParameter i co masz na myśli przez "statyczną" treść i zawartość jersey'a? – sreya

+0

Treść statyczna jest treścią, która nie jest dynamiczna i pozostaje statyczna bez względu na to, kto ją prosi (np. obrazy, javascript, css, itp.). Zasoby Jersey są objęte scenariuszami zawartości dynamicznej. Rzeczy wygenerowane przez Twój kod, które zostaną odesłane do użytkownika końcowego (przeglądarki). Jeśli chodzi o błąd 500, zaktualizuj swoje pytanie za pomocą wygenerowanego stosu. Również wiem, że nie mogę komentować specyfiki Jersey (ponieważ tak naprawdę ich nie znam, jestem deweloperem Jetty) –

+0

Nie mam śladu stosu :(, zakładam, że mogę po prostu uruchomić program z głównego klasy? Czy muszę uruchomić z katalogu projektu?Czy to ma sens – sreya

9

Jeśli chcesz całkowicie programowo zarządzać cyklem życia zasobu DBCollection (np. Samodzielnie utworzyć instancję, zrób trochę konfiguracji/inicjalizacji itp), zamiast Jersey utworzyć instancję dla ciebie, możesz użyć ResourceConfig jak takie:

ServletContextHandler sch = new ServletContextHandler(); 
sch.setContextPath("/xxx"); 

TheResource resource = new TheResource(); 
ResourceConfig rc = new ResourceConfig(); 
rc.register(resource); 

ServletContainer sc = new ServletContainer(rc); 
ServletHolder holder = new ServletHolder(sc); 
sch.addServlet(holder, "/*"); 

Server server = new Server(port); 
server.setHandler(sch); 
server.start(); 
server.join(); 

Uwaga linia TheResource resource = new TheResource();. Tutaj tworzymy własną instancję TheResource i możemy manipulować nią teraz.

Powiązane problemy