web-dev-qa-db-ja.com

web.xml、サーブレット3.0、およびジャージーを使用したJAX-RSアプリケーションのデプロイ

Web.xml、servlet 3.0、およびjerseyAPIを使用してアプリケーションをデプロイしようとしています。残念ながら、それは機能しません。

これは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)

どうしましたか ? :/ Tomcat7を使用しています。

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>

しかし、後で非同期モードが必要になります。

ありがとう!

6
Holyheart

更新:この回答を書いた後、公式のGlassfish Jersey実装を使用して、Tomcatでweb.xmlが必要にならないようにする方法を見つけました。詳細は こちら をご覧ください。

標準のTomcatインストール(またはその他のサーブレットコンテナ)を使用している場合は、web.xmlファイル*で開始するサーブレットを明示的に指示することを避けられません。とにかくweb.xmlを使用する必要があるため、RESTful Webサービスを機能させる最も簡単な方法は、javax.ws.rs.core.Applicationを完全に拡張することを忘れ、そこでコンテキストパスを指定することです。標準のjax-rsアノテーションを使用して、実際のWebサービスを宣言することもできます。

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>

2つの注目すべき点:

  1. サーブレットコンテナには通常は含まれていないため、REST実装をWARファイルにバンドルする必要があります。JerseyはJAX-RSのリファレンス実装であるため、これを使用しています。上記のservlet-class要素にあります。必要に応じて、これをApacheCXF実装に置き換えることができます。

  2. init-param要素は、どのパッケージを検索するかをジャージーに指示しますJava Webサービスアノテーション付きのファイル。これを編集してWebサービスを指すようにします。ApacheCXFを使用する場合は注意してください。ジャージーの代わりに、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>

この後、Javaクラスで標準のJAX-RSアノテーションを使用して、Webサービスを宣言するのは簡単です。

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)。

乾杯!

* web.xmlを使用せずにTomcatのコンテキストにJerseyサーブレットを追加する方法を知っている場合は、誰かが私を訂正してください。おそらく、コンテキストまたはライフサイクルリスナーを使用しますか?

8
Alvin Thompson
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;
   }
}
0
Jaya Madhuri

次のコード行を使用して、WEB-INFフォルダーの下にweb.xmlを作成する必要があります。

<?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クラスを削除できます。 Webサービスをデプロイしてテストします。それが動作します

0
java baba