Czy można skonfigurować aplikację JAX-RS tylko przy użyciu adnotacji? (przy użyciu Servlet 3.0 i JAX-RS Jersey 1.1.0)
Próbowałem i nie miałem szczęścia. Korzystanie z niektórych web.xml
wydaje się wymagane.
Konfiguracja A (działa, ale ma konfigurację 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>
...
Jawa
@ApplicationPath("/")
public class MyApplication extends Application {
...
}
Konfiguracja B (nie działa, zgłoszony wyjątek)
@ApplicationPath("/")
@WebServlet("/*") // <--
public class MyApplication extends Application {
...
}
Ten ostatni wydaje się nalegać, że aplikacja będzie podklasą serwletu (wyjątek nie pozostawia domysłów)
java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet
pytania
Dlaczego definicja web.xml zadziałała, a adnotacja nie? Co za różnica?
Czy jest sposób, aby to zadziałało, np. Mieć aplikację JAX-RS bez pliku web.xml?
java
jakarta-ee
jax-rs
servlet-3.0
Eran Medan
źródło
źródło
Odpowiedzi:
** PRZECZYTAJ, JEŚLI UŻYWASZ TOMCAT LUB JETTY! **
Odpowiedź Zaakceptowany ma pracy, ale tylko wtedy, gdy jest wdrożony webapp do serwera aplikacji, takich jak GlassFish lub JBoss Application Server i ewentualnie serwletów pojemników z rozszerzeniami EE jak TomEE. To nie działa na standardowych kontenerach serwletów jak Tomcat, którego jestem pewien, że większość ludzi szuka rozwiązania tutaj chcesz użyć.
Jeśli używasz standardowej instalacji Tomcat (lub innego kontenera serwletów), musisz dołączyć implementację REST, ponieważ Tomcat jej nie zawiera. Jeśli używasz Mavena, dodaj to do
dependencies
sekcji:<dependencies> <dependency> <groupId>org.glassfish.jersey.bundles</groupId> <artifactId>jaxrs-ri</artifactId> <version>2.13</version> </dependency> ... </dependencies>
Następnie po prostu dodaj klasę konfiguracji aplikacji do swojego projektu. Jeśli nie masz żadnych specjalnych potrzeb konfiguracyjnych poza ustawieniem ścieżki kontekstu dla pozostałych usług, klasa może być pusta. Po dodaniu tej klasy nie musisz niczego konfigurować
web.xml
(lub w ogóle ją mieć):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 {}
Następnie deklarowanie usług internetowych jest proste przy użyciu standardowych adnotacji JAX-RS w klasach 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); } }
To powinno wystarczyć. Jeśli twoja instalacja Tomcat działa lokalnie na porcie 8080 i wdrażasz plik WAR w kontekście
myContext
, przechodzisz do ...... powinien przynieść oczekiwany rezultat (5).
źródło
web.xml
nie ma go. W twojejpom.xml
mocy „build> Wtyczki”, dodać (jeśli jeszcze nie istnieje)<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>2.3</version><configuration><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin>
.<failOnMissingWebXml>false</failOnMissingWebXml>
opcja.Application
i nie dodałeś@ApplicationPath
do niej adnotacji. Klasa może być pusta, ale musi tam być.jersey-container-servlet
, bez ciągnięcia całejjaxrs-ri
zależności. Np. W moim przypadku był to'org.glassfish.jersey.core:jersey-server:2.18'
+'org.glassfish.jersey.containers:jersey-container-servlet:2.18'
.Wygląda na to, że wszystko, co musiałem zrobić, to to (Servlet 3.0 i nowsze)
import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("/*") public class MyApplication extends Application { ... }
I najwyraźniej nie była potrzebna żadna konfiguracja web.xml (próbowano na Tomcat 7)
źródło
Rozdział 2 specyfikacji JAX-RS: Java ™ API for RESTful Web Services opisuje proces publikacji aplikacji JAX-RS w środowisku Servlet (sekcja 2.3.2 Servlet w specyfikacji).
Należy pamiętać, że środowisko Servlet 3 jest zalecane tylko (sekcja 2.3.2 Servlet, strona 6):
Krótko mówiąc, jeśli chcesz zastosować podejście bez web.xml, jest to możliwe dzięki niestandardowej implementacji aplikacji javax.ws.rs.core.Application, która rejestruje zasoby usługi RESTful z adnotacją javax.ws.rs.ApplicationPath .
@ApplicationPath("/rest")
Chociaż pytałeś konkretnie o Jersey, możesz również przeczytać artykuł Implementing RESTful services with JAX-RS i WebSphere 8.5 Liberty Profile, w którym opisałem proces publikacji no-web.xml dla WebSphere Liberty Profile (z Apache Wink jako implementacją JAX-RS).
źródło
@ApplicationPath("")
usług REST w katalogu głównym (względem katalogu głównego aplikacji sieci Web) na JBoss EAP 7. Nie mambeans.xml
aniweb.xml
.Musisz ustawić odpowiednie zależności w 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>
Więcej szczegółów tutaj: Przykład startowy dla jax-rs
źródło
<failOnMissingWebXml>
Wspomniane wcześniej zależności nie działają u mnie. Z podręcznika użytkownika Jersey:
https://jersey.github.io/documentation/latest/deployment.html#deployment.servlet.3
źródło
Jak zauważył @ Eran-Medan, JBoss EAP 7.1 (uwaga bez aplikacji internetowej, więc bez serwletu, robiłem to w projekcie EJB 3.2) musiałem dodać atrybut „value” jako taki, ponieważ otrzymałem wyjątek, że atrybut wartości był wymagany.
To zadziałało dla mnie
@ApplicationPath(value="/*") public class MyApplication extends Application { private Set singletons = new HashSet(); public MyApplication() { singletons.add(new MyService()); } ... }
Ślad stosu
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
źródło