restful web services HTTP Status 404 - Not Found - rest

After deploying the ejb project and the web project on glassfish and when I run my webservice PatientService I have HTTP Status 404 - Not Found. this is my code :
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
#Named
#Path("/patient")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public class PatientService {
#Inject
private PatientEntityFacade patientEntityFacade;
#Context
private UriInfo uriInfo;
#GET()
#Path("/findALL")
public List<PatientEntity> findAll(){
return patientEntityFacade.findAll();
}
}
And this is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
can you help me please ?

Related

#EJB annotation not working for REST API class file

#EJB not working, returning null pointer exception when used. I am using jersey. It is working in the similar project of jersey earlier.
Rest API class
#Path("")
public class Services
{
#EJB
UserSessionBeanLocal userBean;
#POST
#Produces(MediaType.APPLICATION_JSON)
#Path("register")
public Response register(#FormParam("userName") final String name, #FormParam("userPassword") final String pass, #FormParam("userEmail") String email)
{
if (userBean.isEmailRegistered(email)) // userBean is null here
{
// code
}
}
}
Stateless EJB
#Stateless
public class UserSessionBean implements UserSessionBeanLocal
{
static ArrayList<User> usersList = new ArrayList<User>();
static int userCount = 0;
User u = null;
#Override
public boolean isEmailRegistered(final String email)
{
return usersList.stream().anyMatch(d -> d.getEmail().equals(email));
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" 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_2_5.xsd">
<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.enovate.assignment.ejb1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/user/*</url-pattern>
</servlet-mapping>
</web-app>
Any help is appreciated. Thanks in advance.
I was expecting it should work fine. Now I have to use the JNDI lookup way to instantiate the bean.
As I mentioned it is working in almost similar project. I found something that #EJB does not work in non-managed bean if is related, but I don't understand it.

HTTP status 500 : Error instantiating servlet class [com.test.Login]

I was following a tutorial, while tring to run this little code I got this error :
HTTP status 500 : Error instantiating servlet class [com.test.Login]
Would you like please to help me to figure a solution
The Servlet :
package com.test;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
public Login() {
// TODO Auto-generated constructor stub
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Welcome !");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
The web.xml :
//In the beggining I had an error in those two first lines just by creating a Dynamic web project before even writing anything so I copied them from a solution of the same problem on stackoverflow, I hope it's not the reason of the error now.
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4">
<display-name>Test</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>Login</display-name>
<servlet-name>Login</servlet-name>
<servlet-class>com.test.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
Error I got :
javax.servlet.ServletException: Error instantiating servlet class [com.test.Login]
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:353)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:872)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1695)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:831)

MessageBodyWriter not found for media type={application/xml, q=1000} - Jersey + Jaxb

I am writing a RESTful web service with Jersey. I want to return a custom object in XML form to consumer. The error I am getting is:
MessageBodyWriter not found for media type={application/xml, q=1000}, type=class com.test.ws.Employee, genericType=class com.test.ws.Employee.
Below is the code:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>com.vogella.jersey.first</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Register resources and providers under com.vogella.jersey.first package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.test.ws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Service Class
package com.test.ws;
#Path("/hello")
public class Hello {
#GET
#Path("/sayHello")
#Produces(MediaType.APPLICATION_XML)
public Employee sayHello() {
Employee employee = new Employee();
employee.setEmpId(1);
employee.setFirstName("Aniket");
employee.setLastName("Khadke");
return employee;
}
}
Employee.java
package com.test.ws;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "employee")
public class Employee {
public String firstName;
public String lastName;
public int empId;
public Employee(String firstName, String lastName, int empId) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.empId = empId;
}
public Employee() {
super();
}
#XmlElement
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#XmlElement
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#XmlElement
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
}
And here is the list of libraries added:
Can anyone help me?
I believe your error is in the web.xml. Try changing your part to this in your web.xml.
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<!-- Register resources and providers under com.vogella.jersey.first package. -->
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.test.ws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
One way to solve your issue is to create a custom javax.ws.rs.core.Application or org.glassfish.jersey.server.ResourceConfig. It seems that your server does not detect your providers for the serialization. By implementing your own Application, you will be able to specify which provider you want to use. for your example, what you could have done is :
MyApplication.java
package com.test.ws;
public class MyApplication extends ResourceConfig {
public MyApplication() {
//register your resources
packages("com.test.ws");
//if you're using Jackson as your XMLProvider for example
register(JacksonJaxbXMLProvider.class);
}
}
And add the application in your deployment file :
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>com.vogella.jersey.first</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.ws.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Employee class should implements Serializable interface
I was able to resolve the issue myself. This was because of having conflicting jars included in build path. Here is the snap for jar files.
I manage a legacy project wich I needed to add a REST web service. This not have Maven.
For jersey 2.25, the last compiled with Java SDK 1.7, I solved adding jar
jersey-media-jaxb-2.25.jar

ContainerRequestFilter ContainerResponseFilter doesn't get called

I am trying to learn jersey by creating a small RESTful service. I want to use the Filters for specific reasons(Like I want to use the ContainerResponseFilter for CORS headers to allow cross domain requests). However, I am just not able to get these filters intercept my call. I have seen all the posts for this problem and most of them say to register with annotation provider or in web.xml.
I have tried registering the files in web.xml as well as giving a #Provider annotation for the container
Here is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e194 -->
<web-app version="2.5" 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_2_5.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/spring/config/BeanLocations.xml</param-value>
</context-param>
<servlet>
<servlet-name>Jersey Web Application</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.rest.example</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.rest.example.cors</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.rest.example.CORSFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.rest.example.RequestFilter</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webresources/*</url-pattern>
</servlet-mapping>
</web-app>
Here are my Filters:
package com.rest.example.cors;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
#Provider
public class CORSFilter implements ContainerResponseFilter {
public ContainerResponse filter(ContainerRequest creq,
ContainerResponse cresp) {
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "*");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
return cresp;
}
}
package com.rest.example.cors;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
#Provider
public class RequestFilter implements ContainerRequestFilter {
public ContainerRequest filter(ContainerRequest request) {
System.out.println("request filter");
return request;
}
}
Link to my github project.
I added a Jersey Application class and registered the filter in the class, which solved my problem. Also upgraded my jersey version to 2.x from 1.x
public class MyApplication extends ResourceConfig {
/**
* Register JAX-RS application components.
*/
public MyApplication () {
register(RequestContextFilter.class);
register(JacksonFeature.class);
register(CustomerResource.class);
register(Initializer.class);
register(JerseyResource.class);
register(SpringSingletonResource.class);
register(SpringRequestResource.class);
register(CustomExceptionMapper.class);
}
}
I solved the problem on Wildfly 10 / rest easy like this (CORSFilter is my ContainerResponseFilter):
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("/rest")
public class JaxRsActivator extends Application {
#Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> resources = new HashSet<Class<?>>();
resources.add(CORSFilter.class);
return resources;
}
}
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>org.anchepedheplatform.infrastructure.core.filters.ResponseCorsFilter</param-value>
</init-param>
First, I wrote a class which implements com.sun.jersey.spi.container.ContainerResponseFilter
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
/**
* Filter that returns a response with headers that allows for Cross-Origin
* Requests (CORs) to be performed against the platform API.
*/
public class ResponseCorsFilter implements ContainerResponseFilter {
#Override
public ContainerResponse filter(final ContainerRequest request, final ContainerResponse response) {
final ResponseBuilder resp = Response.fromResponse(response.getResponse());
resp.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
final String reqHead = request.getHeaderValue("Access-Control-Request-Headers");
if (null != reqHead && !reqHead.equals(null)) {
resp.header("Access-Control-Allow-Headers", reqHead);}
response.setResponse(resp.build());
return response;
}
and later I had put this reference of this class in intit-param web.xml.
If you are extending the ResourceConfig class the process of registering all the providers can be tedious one and chances are there that one can even miss few providers.
What here can be done with a type of ResourceConfig is you can use packages method in the default constructor to specify the packages("") which will contain your rest resources and the providers. For Instance lets say we have a package com.test.poc.rest which contains all the rest services and another package namely com.test.poc.providers then our resourceConig will look like:
public class CustomResourceConfig extends ResourceConfig{
public CustomResourceConfig(){
super();
packages("com.test.poc.rest;com.test.poc.providers");
//register any custom features
register(JacksonFeature.class); // enabling JSON feature.
}
}
and boom jersey will now scan for your webservices annotated with #Path and for the providers annotated with #Provider.

RESTful Service using Jersey

Please find the following code.
Service:DataResource.java
package com.mypack.pack2;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import com.mypack.pack1.DataClass;
#Path("data")
public class DataResource {
//Just retrieves the data members of the class
//i.e., 10 Ram
// Able to retrieve successfully.
#GET
#Produces("text/plain")
public String display()
{
DataClass obj1=new DataClass();
return obj1.getId()+obj1.getName();
}
#POST
#Path("/{id}/{name}")
#Produces("text/plain")
#Consumes("text/plain")
public void newData(#PathParam("id") int no,
#PathParam("name") String name) {
DataClass obj= new DataClass();
obj.setData(name,no);
System.out.println("Success");
System.out.println("Data after changes"+obj.getId()+obj.getName());
}
//TodoDao.instance.getModel().put(id, todo);
}
DataClass.java
package com.mypack.pack1;
public class DataClass {
private String ename="Ram";
private int eno=10;
public void setData(String name,int no)
{
this.ename=name;
this.eno=no;
}
public int getId()
{
return eno;
}
public String getName()
{
return ename;
}
}
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>de.vogella.jersey.jaxb</display-name>
<servlet>
<servlet-name>Jersey REST Service</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.mypack.pack2</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I am not able to change the values of class members ename and eno of DataClass. Can anyone please tell me why it is not changing? Is it because i am trying the code in a wrong way?
How are you invoking the POST URI (localhost:8080/JerseyProject/rest/data/11/John)? Be sure you are not invoking it from your browser, cause this way you would be invoking the verb GET o the /data/{id}/{name} that doesn't have implementation. That would explain why you're getting the status 405.
Usually the CREATE operation is used using the HTTP VERB POST on the collection URI with its params in the payload not on the path. In this case using POST on /data instead of /data/{id}/{name}.