[java] 어노테이션 만 사용하여 (web.xml 없음) JAX-RS 애플리케이션을 설정하는 방법은 무엇입니까?

어노테이션 만 사용하여 JAX-RS 애플리케이션을 설정할 수 있습니까? (Servlet 3.0 및 JAX-RS Jersey 1.1.0 사용)

나는 시도했지만 운이 없었다. 일부 사용 web.xml이 필요한 것 같습니다.


구성 A (작동하지만 web.xml 구성이 있음)

web.xml

   ...
   <servlet>
      <servlet-name>org.foo.rest.MyApplication</servlet-name>
   </servlet>
   <servlet-mapping>
       <servlet-name>org.foo.rest.MyApplication</servlet-name>
       <url-pattern>/*</url-pattern>
   </servlet-mapping>
   ...

자바

@ApplicationPath("/")
public class MyApplication extends Application {
    ...
}

구성 B (작동하지 않음, 예외 발생)

@ApplicationPath("/")
@WebServlet("/*") // <-- 
public class MyApplication extends Application {
    ...
}

후자는 응용 프로그램이 Servlet의 하위 클래스가 될 것이라고 주장하는 것 같습니다 (예외가 추측을 남기지 않음).

java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet

질문

  1. web.xml 정의가 작동했지만 주석이 작동하지 않은 이유는 무엇입니까? 차이점이 뭐야?

  2. 예를 들어 web.xml이없는 JAX-RS 애플리케이션을 사용하는 것과 같이 작동하도록하는 방법이 있습니까?



답변

** TOMCAT 또는 JETTY를 사용하는 경우 읽으십시오! **

허용되는 답변 작동하지만 Webapp이 Glassfish 또는 Wildfly와 같은 앱 서버 및 TomEE와 같은 EE 확장이있는 서블릿 컨테이너에 배포 된 경우에만 작동합니다. 그것은 하지 않습니다 내가 여기 사용 하시겠습니까 솔루션을 찾고 대부분의 사람들이야 톰캣 같은 표준 서블릿 컨테이너에서 작동합니다.

표준 Tomcat 설치 (또는 다른 서블릿 컨테이너)를 사용하는 경우 Tomcat에 REST 구현이 포함되어 있지 않으므로 REST 구현을 포함해야합니다. Maven을 사용하는 경우 dependencies섹션에 다음 을 추가 하십시오.

<dependencies>
  <dependency>
    <groupId>org.glassfish.jersey.bundles</groupId>
    <artifactId>jaxrs-ri</artifactId>
    <version>2.13</version>
  </dependency>
  ...
</dependencies>

그런 다음 프로젝트에 애플리케이션 구성 클래스를 추가하기 만하면됩니다. 나머지 서비스에 대한 컨텍스트 경로를 설정하는 것 외에 특별한 구성이 필요하지 않은 경우 클래스가 비어있을 수 있습니다. 이 클래스가 추가되면 다음에서 아무것도 구성 할 필요가 없습니다 web.xml.

package com.domain.mypackage;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("rest") // set the path to REST web services
public class ApplicationConfig extends Application {}

그런 다음 Java 클래스의 표준 JAX-RS 어노테이션을 사용하여 웹 서비스 선언이 간단합니다.

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


답변

내가해야 할 일은 이것 뿐인 것 같습니다 (서블릿 3.0 이상)

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/*")
public class MyApplication extends Application {
    ...
}

그리고 web.xml 구성이 분명히 필요하지 않았습니다 (Tomcat 7에서 시도)


답변

JAX-RS : RESTful 웹 서비스 용 Java ™ API 사양의 2 장 에서는 Servlet 환경에서 JAX-RS 애플리케이션의 게시 프로세스를 설명합니다 ( 사양의 섹션 2.3.2 Servlet ).

Servlet 3 환경 만 권장됩니다 (섹션 2.3.2 Servlet, 페이지 6) :

구현시 Servlet 3 프레임 워크 플러그 가능성 메커니즘을 지원하여 컨테이너 간의 이식성을 활성화하고 컨테이너에서 제공하는 클래스 스캔 기능을 사용할 수 있도록하는 것이 좋습니다.

간단히 말해서 no-web.xml 접근 방식을 사용하려는 경우 javax.ws.rs.ApplicationPath 주석으로 RESTful 서비스 리소스를 등록 하는 javax.ws.rs.core.Application 의 사용자 지정 구현을 통해 가능합니다 .

@ApplicationPath("/rest")

당신은 기사 읽기님께 추천 뉴저지에 대해 구체적으로 질문하지만 JAX-RS 및 WebSphere 8.5 자유 프로필에 구현하여 RESTful 서비스 I가 노 web.xml을 게시 과정을 설명하는 는 WebSphere 자유 프로파일 의 구현으로 아파치 윙크와을 ( JAX-RS).


답변

pom.xml에 올바른 종속성을 설정해야합니다.

<dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
    </dependency>

자세한 내용은 여기 :
jax-rs의 시작 예제


답변

이전에 언급 한 종속성이 저에게 효과적이지 않았습니다. Jersey 사용 설명서에서 :

Jersey는 두 개의 Servlet 모듈을 제공합니다. 첫 번째 모듈은 핵심 Servlet 통합 지원을 제공하는 Jersey 핵심 Servlet 모듈이며 모든 Servlet 2.5 이상 컨테이너에 필요합니다.

<dependency>
 <groupId>org.glassfish.jersey.containers</groupId>
 <artifactId>jersey-container-servlet-core</artifactId>
</dependency>

추가 Servlet 3.x 배치 모드 및 비동기 JAX-RS 자원 프로그래밍 모델을 지원하려면 추가 Jersey 모듈이 필요합니다.

<dependency>
 <groupId>org.glassfish.jersey.containers</groupId>
 <artifactId>jersey-container-servlet</artifactId>
</dependency>

jersey-container-servlet 모듈은 jersey-container-servlet-core 모듈에 의존하므로 사용시 jersey-container-servlet-core 종속성을 명시 적으로 선언 할 필요가 없습니다.

https://jersey.github.io/documentation/latest/deployment.html#deployment.servlet.3


답변

@ Eran-Medan이 지적했듯이 JBoss EAP 7.1 (웹 응용 프로그램이 없어서 서블릿이 없어서 EJB 3.2 프로젝트에서 수행했습니다) 나는 “value”속성을 추가해야했습니다. 값 속성이 필요합니다.

이것은 나를 위해 일했습니다.

    @ApplicationPath(value="/*")
        public class MyApplication extends Application {

            private Set singletons = new HashSet();

            public MyApplication() {
                singletons.add(new MyService());
            }

            ...
    }

스택 추적

    Caused by: java.lang.annotation.IncompleteAnnotationException: javax.ws.rs.ApplicationPath missing element value
        at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:80)
        at com.sun.proxy.$Proxy141.value(Unknown Source)
        ... 21 more


답변