Java RESTful Service - 404 Not Found - java

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.

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.

How to annotate JAX-RS on an interface while using Jersey

This question had been asked a few times before, however the answers doesn't seem to work and/or Jersey has moved on with more changes.
I'm exposing some REST APIs using JAX-RS and Jersey (version 2.24). And I wish to annotate the interface with JAX-RS and a concrete implementation (without any annotations). However, since this patch Jersey stopped supporting this possibility. As far as I understand the spec, it doesn't strictly prohibit doing that.
If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the superclass or interface method are ignored.
implying that it is totally okay to do that. In many cases it is good to use an interface, and have a server and client each have their respective implementations.
There are plenty of solutions out there,
Use a ResourceConfig and do a registerClasses(MyImplementation.class) . However, this doesn't work.
Disable the package scanning configuration in web.xml, create a custom javax.ws.rs.Application and do a register of your implementation from there. Doesn't work.
use a ResourceConfig and define a custom AbstractBinder and do a bind so that Jersey's dependency injection can find the concrete implementations. Doesn't work.
Use RESTEasy. RESTEasy doesn't seem to impose the interface restrictions as in Jersey. Never tried it myself.
I would appreciate if someone can share their experience with this. Any help on how to get Jersey working would be great too. As for the option (4) is it really necessary to switch ? A sample code below.
MyResource
package com.foo;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Path("/hello")
public interface MyResource {
#GET
public String sayHello();
}
MyResourceImpl
package com.bar;
public class MyResourceImpl implements MyResource {
#Override
public String sayHello() {
return "Hello Jersey";
}
}
Also have a web.xml that has the package scanning enabled to scan com.foo
If you want to separate Resource interface from implementation (allowing you to use the interface with some REST client like resteasy client) you can use #RequestScoped on the implementation. Thus, this bean could use injected resources like EJB, EntityManager, ...
Using your sample :
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Path("/hello")
public interface MyResource {
#GET
public String sayHello();
}
MyResourceImpl
package com.bar;
#RequestScoped
public class MyResourceImpl implements MyResource {
#Override
public String sayHello() {
return "Hello Jersey";
}
}
Nevertheless, you have to take into consideration that as soon as you use specific JAX-RS classes in your implementation code (like UriInfo, Response object, ...) you will create a coupling between your implementation and the JAX-RS API.
In Jersey,We should Put the class level #Path on the implementation instead of the interface.
package com.foo;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Path("/hello")
public interface MyResource {
#GET
public String sayHello();
}
MyResourceImpl
package com.bar;
#Path("/hello")
public class MyResourceImpl implements MyResource {
#Override
public String sayHello() {
return "Hello Jersey";
}
}

Ho does Jersey Resource config package scanner work

I have something like this
#ApplicationPath("/")
public class MyJaxRSApplication extends ResourceConfig {
public MyJaxRSApplication() {
String[] packages = {"com.xxx.xyz.rules.rest"};
packages(packages);
}
}
I do have a security service to intercept request
package com.xxx.xyz.rules.restfilter;
#Priority(20)
#Provider
public class UrlBasedAuthorizationFilter implements ContainerRequestFilter {
}
Above code snippet is working, but I can't get my hear-around understanding how jersey scanning works. Does it takes as "com.xxx.xyz.rules.rest*".
I haven't tested it, but if what you are showing works, then it looks like a bug (rather than a feature) to me. How it's documented to work is to scan the exact package specified, and all its subpackages, recursively
com.xxx.xyz.rules.rest
com.xxx.xyz.rules.rest.sub1
com.xxx.xyz.rules.rest.sub1.sub2
com.xxx.xyz.rules.rest.sub1.sub2.tillstackoverflow

Why can't my EJB ReST service extend an abstract class from a seperate jar?

So, I have a stateless EJB in a .war file.
This EJB is used as a ReST service.
In an jar, I have an abstract class with some methods implemented.
The service EJB extends the abstract class from the jar.
When I try to deploy this .war file to WebLogic 12c, I get the following error:
AppMerge failed to merge your application.
I am unsure as to why this error occurs.
This is what my abstract class looks like in the jar:
public abstract class AbstractService
{
public Response runService(final ServiceParams parameter)
{
return Response.ok().build();
}
}
This is what the service implementation looks like in the war:
#Path("/")
#Stateless
public class MyService extends AbstractService
{
#GET
#Path("/run")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Override
public Response runService(final #QueryParam("jsonParamObjectId") ServiceParams parameter)
{
return super.runService(parameter);
}
}
This configuration and code deploys successfully in Glassfish 3.1.2.2.
Any ideas as to why WebLogic 12c is giving me issues?
I'm sure this is a classloading issue whose solution I keep missing.
Thanks in advance for any insights!

Loading resources using Jersey and #ApplicationPath annotation

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.

Categories