2013-09-03 3 views
4

Я пытаюсь развернуть свое приложение, используя web.xml, servlet 3.0 и jersey API. К сожалению, это не сработает.Развертывание приложения JAX-RS с использованием web.xml, Servlet 3.0 и Jersey

Это MyApplication.class:

package com.example; 

public class MyApplication extends Application { 
    public Set<Class<?>> getClasses() { 
     Set<Class<?>> s = new HashSet<Class<?>>(); 
     s.add(MyResource.class); 
     return s; 
    } 
} 

Это MyResource:

@Path("/helloworld") 
@Produces(MediaType.TEXT_PLAIN) 
public class MyResource { 
    @GET 
    public String getHello() { 
     return "HelloWorld !"; 
    } 
} 

И моя web.xml:

<web-app> 
    <servlet> 
     <servlet-name>com.example.MyApplication</servlet-name> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>com.example.MyApplication</servlet-name> 
     <url-pattern>/webapi/*</url-pattern> 
    </servlet-mapping> 
</web-app> 

На стороне клиента, я использую это url: http: // localhost: 8080/[projectname]/webapi/helloworld

И у меня есть эта ошибка:

java.lang.NullPointerException 
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) 
    java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1629) 
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559) 
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:491) 
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) 
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852) 
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) 
    java.lang.Thread.run(Thread.java:662) 

Что случилось? :/Я использую Tomcat 7.

PS: с сервлета 2.x, это работает:

<servlet> 
     <servlet-name>Jersey Web Application</servlet-name> 
     <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
     <init-param> 
      <param-name>jersey.config.server.provider.packages</param-name> 
      <param-value>com.example</param-value> 
     </init-param> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>Jersey Web Application</servlet-name> 
     <url-pattern>/webapi/*</url-pattern> 
    </servlet-mapping> 

, но я буду нуждаться в асинхронном режиме позже.

Спасибо!

+0

С момента написания своего ответа, я нашел способ избежать необходимости использования «web.xml» на Tomcat, используя официальную реализацию Jerseyfish Jersey. Это так же просто, как этот метод, если не проще. Посмотрите [здесь] (http://stackoverflow.com/questions/9373081/how-to-set-up-jax-rs-application-using-annotations-only-no-web-xml/26721737#26721737) для деталей. –

ответ

7

Update: С момента написания этого ответа, я нашел способ, чтобы избежать необходимости в web.xml на сервере Tomcat с помощью официальной реализации Glassfish Джерси. Посмотрите here для деталей.

Если вы используете стандартную установку Tomcat (или какой-либо другой контейнер сервлетов), AFAIK вы не можете явно указывать, какие сервлеты должны запускаться в файле web.xml *. Так как в любом случае вам нужно использовать web.xml, самый простой способ получить работу в обслуживании веб-сервисов - это полностью отказаться от расширения javax.ws.rs.core.Application и просто указать путь к нему. Вы можете использовать стандартные аннотации jax-rs для объявления фактических веб-сервисов.

web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0" 
> 
    <servlet> 
    <servlet-name>rest-test</servlet-name> 
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.packages</param-name> 
     <param-value>com.domain.mypackage</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name> rest-test</servlet-name> 
    <url-pattern>/rest/*</url-pattern> 
    </servlet-mapping> 
</web-app> 

Два примечательных точки:

  1. Вам нужно будет связать реализацию REST в файле WAR, так как контейнеры сервлетов не содержат обычно один. Поскольку Джерси является эталонной реализацией JAX-RS, это тот, который я использую в элементе servlet-class выше.Вы можете заменить это на реализацию Apache CXF, если хотите.

  2. Элемент init-param сообщает Джерси, который из ваших пакетов ищет файлы Java с аннотациями веб-сервиса. Отредактируйте это, чтобы указать на свои веб-службы. Обратите внимание: если вы решите использовать apache CXF вместо Jersey, то материал, необходимый в любых элементах init-param, будет отличаться. Кто-то, кто знает CXF, напишите, что они будут.

Если вы используете Maven, просто добавить зависимость к jersey-servlet в dependencies разделе вашего pom.xml файла:

<dependencies> 
    <dependency> 
    <groupId>com.sun.jersey</groupId> 
    <artifactId>jersey-servlet</artifactId> 
    <version>1.18.2</version> 
    </dependency> 
    ... 
</dependencies> 

После этого, объявляя свои веб-сервисы прямо вперед, используя стандартный JAX -RS в ваших Java-классах:

package com.domain.mypackage; 
import javax.ws.rs.Consumes; 
import javax.ws.rs.Produces; 
import javax.ws.rs.GET; 
import javax.ws.rs.MatrixParam; 
import javax.ws.rs.Path; 

// It's good practice to include a version number in the path so you can have 
// multiple versions deployed at once. That way consumers don't need to upgrade 
// right away if things are working for them. 
@Path("calc/1.0") 
public class CalculatorV1_0 { 
    @GET 
    @Consumes("text/plain") 
    @Produces("text/plain") 
    @Path("addTwoNumbers") 
    public String add(@MatrixParam("firstNumber") int n1, @MatrixParam("secondNumber") int n2) { 
    return String.valueOf(n1 + n2); 
    } 
} 

Это должно быть все, что вам нужно. Если Tomcat установки работает локально на порту 8080 и развертывании файла WAR в контексте myContext, собирается

http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3 

... следует производить ожидаемый результат (5).

Cheers!

* Кто-нибудь, пожалуйста, исправьте меня, если вы знаете способ добавить сержанта Джерси к контексту в Tomcat без использования web.xml - возможно, используя контекст или прослушиватель жизненного цикла?

+2

С момента написания этого ответа я обнаружил способ избежать необходимости использования «web.xml» на Tomcat, используя официальную реализацию Jerseyfish Jersey. Посмотрите [здесь] (http://stackoverflow.com/questions/9373081/how-to-set-up-jax-rs-application-using-annotations-only-no-web-xml/26721737#26721737) для деталей. –

-1

Вам нужно создать файл web.xml в папке WEB-INF с следующей строки кода

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
    <servlet> 
     <servlet-name>ServletAdaptor</servlet-name> 
     <servlet-class> 
      org.glassfish.jersey.servlet.ServletContainer 
     </servlet-class> 
     <init-param> 
      <param-name>jersey.config.server.provider.packages</param-name> 
      <param-value>package where MyResource resides</param-value> 
     </init-param> 
     <init-param> 
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
      <param-value>true</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>ServletAdaptor</servlet-name> 
     <url-pattern>/webresources/*</url-pattern> 
    </servlet-mapping> 
    <session-config> 
     <session-timeout> 
      30 
     </session-timeout> 
    </session-config> 
</web-app> 

Теперь вы можете удалить MyApplication класса. Развертывание и тестирование веб-сервиса. он будет работать

-1

Посетите эту ссылку, может помочь: https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.2

раздел: 4.7.1. Servlet 2.x Контейнер

<web-app> 
    <servlet> 
     <servlet-name>MyApplication</servlet-name> 
     <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> 
     <init-param> 
      ... 
     </init-param> 
    </servlet> 
    ... 
    <servlet-mapping> 
     <servlet-name>MyApplication</servlet-name> 
     <url-pattern>/myApp/*</url-pattern> 
    </servlet-mapping> 
    ... 
</web-app> 
0
package com.example; 

@ApplicationPath("/webapi") 

public class MyApplication extends Application { 

    public Set<Class<?>> getClasses() { 
     Set<Class<?>> s = new HashSet<Class<?>>(); 
     s.add(MyResource.class); 
     return s; 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^