使用web.xml,Servlet 3.0和Jersey部署JAX-RS应用程序 [英] Deployment of a JAX-RS application using web.xml, Servlet 3.0 and Jersey

查看:110
本文介绍了使用web.xml,Servlet 3.0和Jersey部署JAX-RS应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用web.xml,servlet 3.0和jersey API部署我的应用程序.不幸的是,它不起作用.

I'm trying to deploy my application, using web.xml, servlet 3.0, and jersey API. Unfortunately, it doesn't work.

这是MyApplication.class:

This is 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:

This is MyResource :

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

还有我的web.xml:

And my 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>

在客户端,我正在使用以下网址: http://localhost:8080/[项目名称]/webapi/helloworld

On client side, I'm using this 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.

What's wrong ? :/ I'm using Tomcat 7.

PS:使用servlet 2.x,它可以工作:

PS : with a servlet 2.x, it works :

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

但是稍后我将需要异步模式.

but i will need asynchronous mode later.

谢谢!

推荐答案

更新:自编写此答案以来,我发现了一种避免使用官方的Tomcat上需要web.xml的方法Glassfish Jersey实施.在此处查看以获得详细信息.

Update: Since writing this answer, I've found out a way to avoid needing a web.xml on Tomcat using the official Glassfish Jersey implementation. Look here for details.

如果您正在使用标准的Tomcat安装(或某些其他servlet容器),则AFAIK不能避免在web.xml文件*中明确告诉它要启动哪些servlet.由于无论如何都必须使用web.xml,因此使宁静的Web服务正常工作的最简单方法是忘记完全扩展javax.ws.rs.core.Application,而只需在其中指定上下文路径即可.您仍然可以使用标准的jax-rs批注来声明实际的Web服务.

If you're using a standard Tomcat install (or some other servlet container), AFAIK you can't avoid explicitly telling it what servlets to start in the web.xml file*. Since you have to use web.xml anyway, the simplest way to get restful web services working is to forget extending javax.ws.rs.core.Application entirely and just specify the context path there. You can still use standard jax-rs annotations to declare the actual web services.

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. 由于servlet容器通常不包含REST实施,因此您需要将REST实施捆绑在WAR文件中.由于Jersey是JAX-RS的参考实现,因此我在上面的servlet-class元素中使用了该实现.您可以根据需要将其替换为Apache CXF实现.

  1. You will need to bundle a REST implementation in your WAR file, since servlet containers don't usually contain one. Since Jersey is the reference implementation for JAX-RS, that's the one I'm using in the servlet-class element above. You can replace this with Apache CXF implementation if you want.

init-param元素告诉Jersey用来搜索带有Web服务注释的Java文件的包.编辑此内容以指向您的Web服务.请注意,如果您选择使用apache CXF而不是Jersey,则所有init-param元素中所需的内容都会有所不同.认识CXF的人请发表他们的想法.

The init-param element tells Jersey which of your packages to search for Java files with web service annotations. Edit this to point to your web services. Note that if you opt to use apache CXF instead of Jersey, the stuff needed in any init-param elements will be different. Someone who knows CXF please post what they would be.

如果使用的是Maven,只需在pom.xml文件的dependencies部分中为jersey-servlet添加依赖项:

If you're using Maven, just add a dependency to jersey-servlet in the dependencies section of your pom.xml file:

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

此后,使用Java类中的标准JAX-RS批注直接声明Web服务:

After this, declaring your web services is straight forward using the standard JAX-RS annotations in your Java classes:

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,则转到

This should be all you need. If your Tomcat install is running locally on port 8080 and you deploy your WAR file to the context myContext, going to

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

...应该产生预期的结果(5).

...should produce the expected result (5).

干杯!

*如果您知道在不使用web.xml的情况下将泽西servlet添加到Tomcat中的上下文的方法,请有人纠正我-也许是使用上下文或生命周期侦听器?

* Someone please correct me if you know of a way to a add the Jersey servlet to the context in Tomcat without using web.xml--maybe by using a context or life cycle listener?

这篇关于使用web.xml,Servlet 3.0和Jersey部署JAX-RS应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆