Loading resources using Jersey and #ApplicationPath annotation - java

I'm trying to deploy a basic jersey restful service to Tomcat7 without web.xml:
#WebServlet(loadOnStartup=1)
#ApplicationPath("resources")
#Path("/mypath/{name}")
public class MyResource extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(MyResource.class);
return s;
}
#GET
#Consumes("text/plain")
#Produces("text/plain")
public String getWelcome(#PathParam(value = "name") String name) {
return "Welcome to jax-rs " + name;
}
}
I'm presented with a 404 when trying to access: /myapplication/resources/mypath/sample.
I can deploy a servlet using the #WebServlet annotation, so this has nothing to do with the loading of servlets without web.xml into Tomcat7.
From reading the documentation for Jersey, the runtime should scan for classes extending Application and execute getClasses(), loading all root resources.

Which version of Jersey are you using? Try splitting application and resource in two classes. Definitely remove #WebServlet annotation. I.e. have one class extending Application annotated with #ApplicationPath and another class annotated with #Path.
EDIT: Make sure that jersey-servlet.jar is included in your WAR file.

Related

javax.mvc run web application

I'm trying to run my web application based on javax.mvc, but I get 404 error. I think there should be an issue related to the application path, but I don't know exactly what's wrong.
XAMPP is installed and IntelliJ idea is configured to run tomcat7 as the web server.
Application code:
#ApplicationPath("web")
public class StoreApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> set = new HashSet<>();
set.add(ProductController.class);
return set;
}
}
Controller:
#Controller
#Path("products")
public class ProductController {
#Inject
private Models models;
#GET
public String list() {
models.put("products", Product.list());
System.out.println("helllo");
return "/WEB-INF/jsp/list.jsp";
}
}
This is a maven project. The build process is done with IntelliJ idea default settings.
Base url is set in StoreApplication.java as web with application path.
The war url is http://localhost:8080/elearning_war/ as depicted in the picture.
And the controller path is products. So I expect to show a list of products in http://localhost:8080/elearning_war/web/products, but instead, I get a 404 error page.
In my opinion, because of #ApplicationPath("web") the URL should be http://localhost:8080/web/products.

Java RESTful Service - 404 Not Found

I am trying to create a RESTful Service in Java using Eclipse, but I have hardly ever worked with this types of projects and I'm getting quite lost trying to create the path of my service, always getting 404 Not Found.
This is my Java class prueba.MyService.java:
package prueba;
import ....
....
#Path("/service")
public class MyService{
#Path("/hello")
#GET
#Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello World()";
}
...
}
This is my prueba.ApplicationConfig.java class, in which I have added the #ApplicationPath annotation:
package prueba;
import ...
...
#ApplicationPath("/rest")
public class ApplicationConfig extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(prueba.MyService.class);
return classes;
}
}
I have also tried to add the <servlet> and <servlet-mapping> tags in the web.xml file, but it didn't solve anything, and based on what I have read here, with the #ApplicationPath annotation should be enough.
After this, I run my service with an Apache Tomcat server and I try to access the http://localhost:8080/rest/service/hello URL, but I get the 404 Not Found error.
Sorry in advance if I am missing something really basic or stupid.
Found the solution by myself:
I have finally started all over again following this tutorial and now it works correctly. Hope it helps.

Trying to instantiate a bean with the CDI from a running webapplication

I have a jar that contains a #Stateless class defined like
#Stateless
public class TestBean() {
#Inject
AnotherBean bean2;
public String getThis() {
return bean2.getAString();
}
}
A webapplication (with a dependency on this jar) running on wildfly 10.1.0 would like to instantiate this bean and use its methods. The webapplication calling method might be a rest endpoint (called by some other webapplication) or just a regular java method.
What is the best way to instantiate TestBean? I have tried several solutions none of which works.
For example this one
Building a CDI 2 standalone
and this one
Does CDI work for regular Java application?
I am new to the CDI and how it works, I am wondering if this is explained well somewhere?
Its not really clear what your question is, but if you have JAX-RS resource, in the WAR file, then this should just work
#Path("/somePath")
#RequestScoped
public class SomeResource {
#Inject
private TestBean testBean;
#GET
public String doGet() {
return testBean.getThis();
}
}

Error Code 404 With Tomcat 8 Webapplication [duplicate]

I have a Struts2 web application running on Tomcat 7.0.43 that uses Rest and Convention plugins to map all requests. Struts tries to map all requests by itself.
JSR 356 defines server end points using annotations like
#ServerEndpoint(value = "/websocket/chat")
Now when the broswer tries to connect to ws:/127.0.0.1:8080/websocket/chat, the request fails because the Struts mapper intercepts the request.
Is there anything I can specify in the XML files, such that the request reaches the right place?
EDIT:
As suggested, I added
<constant name="struts.action.excludePattern" value="/websocket.*?" />
to my Struts configuration, after which the URL /websocket/chat started reaching a 404 error.
Later I learnt that I need to configure a ServerApplicationConfig implementation. After doing that the websocket starts working fine but the rest of my application fails to load giving an error:
SEVERE: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
Here is my class:
public class Socket implements ServerApplicationConfig {
#Override
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> scanned) {
Set<ServerEndpointConfig> result = new HashSet<ServerEndpointConfig>();
return result;
}
#Override
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
Set<Class<?>> results = new HashSet<Class<?>>();
for (Class<?> clazz : scanned) {
results.add(clazz);
}
return results;
}
}
How can I get everything to work together in Harmony?
Note: I am using Struts Spring Plugin for Dependency Injection of Spring Security.
You can configure the Struts filter to exclude some URLs via regex pattern. You should add the constant in the struts.xml
<constant name="struts.action.excludePattern" value="^ws://.+$"/>
Use Websocket API for server endpoints.

JAX-RS Application subclass injection

I'm writing custom JAX-RS 2.0 application (under Jersey 2.3.1) which holds some data for use by all the resources.
public class WebApp extends org.glassfish.jersey.server.ResourceConfig {
public WebApp() {
packages("my.resources.package");
}
}
(I could use API's javax.ws.rs.core.Application as well, the described result is the same)
Then I inject the object into a resource
#Path("test")
public class Test {
#Context
Application app;
#GET
#Path("test")
public String test() {
return "Application class: " + app.getClass();
}
}
However, the result of a call is
Application class: class org.glassfish.jersey.server.ResourceConfig$WrappingResourceConfig
which makes me use some ugly tricks like
if (app instanceof WebApp) {
return (WebApp) app;
} else if (app instanceof ResourceConfig) {
return (WebApp) ((ResourceConfig) app).getApplication();
}
My understanding of JAX-RS 2.0 spec section 9.2.1:
The instance of the application-supplied Application subclass can be injected into a class field or method parameter using the #Context annotation. Access to the Application subclass instance allows configuration information to be centralized in that class. Note that this cannot be injected into the Application subclass itself since this would create a circular dependency.
is that application-supplied Application subclass is mine WebApp, not JAX-RS implementation-specific wrapper.
Also, changing this fragment
#Context
Application app;
to this
#Context
WebApp app;
causes app to be null, due to ClassCastException during context injection, so the declared type doesn't matter.
Is it a bug in Jersey or my misunderstanding?
UPDATE: I checked the behaviour under RESTEasy 3.0. The injected object is my WebApp, without any wrappers. I'd call it a bug in Jersey.
This doesn't seem like a bug. According to JAX-RS 2.0 spec you can inject Application into your resource classes (for example) but it does not say anything about directly injecting custom extensions of the Application. Not sure what your use-case is but you can register custom HK2 binder that will allow you to inject directly WebApp into resources:
public class WebApp extends org.glassfish.jersey.server.ResourceConfig {
public WebApp() {
packages("my.resources.package");
register(new org.glassfish.hk2.utilities.binding.AbstractBinder() {
#Override
protected void configure() {
bind(WebApp.this);
}
});
}
}
I too have encountered this using Jersey 2.4.1.
FWIW: I agree it seems like a bug according to the spec para 8.2.1. The statement "The instance of the application-supplied Application subclass" seems perfectly clear.
I have an alternative workaround that doesn't involve glassfish.hk2 but still concentrates the Jersey-specific code in the Application-derived class.
public class MyApp extends ResourceConfig {
...
static MyApp getInstance( Application application) {
try {
// for a conformant implementation
return (MyApp) application;
} catch (ClassCastException e) {
// Jersey 2.4.1 workaround
ResourceConfig rc = (ResourceConfig) application;
return (MyApp) rc.getApplication();
}
}
...
}
public class MyResource {
...
#Context Application application;
...
SomeMethod() {
... MyApp.getInstance( application);
}
}
Hope this is useful.
This appears to be fixed in a later version og Jersey. The same approach works for me with Jersey 2.16 at least. My injected Application object is of the correct subclass without any wrapping whatsoever.
Edit: Or maybe the version is irrelevant after all. Please see the comments to this answer.

Categories