I getting started with Java and rest services, i created a rest service with GET method, this method return a UserVO with his properties, im set properties values with random values using setMethods and return object but this not work mapping object to json of jersey. I using tomcat 6, JDK 1.8.0_121 and eclipse and show this error:
com.sun.jersey.spi.container.ContainerResponse write
GRAVE: A message body writer for Java class Autoconsulta.ValueObject.UsuarioVO, and Java type class Autoconsulta.ValueObject.UsuarioVO, and MIME media type application/json was not found.
The registered message body writers compatible with the MIME media type are:
application/json ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
VO
public class UsuarioVO {
private String rut;
private boolean isValid;
public String getRut() {
return rut;
}
public void setRut(String rut) {
this.rut = rut;
}
public boolean isValid() {
return isValid;
}
public void setValid(boolean isValid) {
this.isValid = isValid;
}
}
my ret service:
#GET
#Path("/getUser")
#Produces({MediaType.APPLICATION_JSON})
public UsuarioVO getUsuario() {
UsuarioVO u = new UsuarioVO();
u.setRut("123444");
u.setValid(true);
return u;
}
web xml
<servlet>
<servlet-name>Servicio_Rest</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>Autoconsulta.ws.rest.service</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Servicio_Rest</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
pom xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
Related
Problem
I have a simple rest application with low complexity built using jersey 2. I use maven for dependency management. I was getting cors issue with post request(JSON) from angular app. It was working fine with other content type except for json payloads. requests with json data was working fine in postman. Then I created a CORSFilter. Now the error is changed and everything is stopped working.
I need
to find whether my project setup is correct or not
to find what the blunder I have done
send post request from angular app with json data and get response
Project deployment assembly
https://imgur.com/a/TolLvEJ
Project facets
https://imgur.com/a/Eqga93Z
My project structure
https://imgur.com/a/VZMP5Vu
I have followed so many suggestions and workarounds. Maybe I was wrongly following them.
My pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>OnlineOrganicMarket</groupId>
<artifactId>OnlineOrganicMarket</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jersey2.version>2.27</jersey2.version>
<jaxrs.version>2.1</jaxrs.version>
</properties>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.2.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<!-- JAX-RS -->
<dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId>
<version>${jaxrs.version}</version> </dependency>
<!-- Jersey 2.19 -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey2.version}</version>
</dependency>
<!-- <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId>
<version>${jersey2.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId> <version>${jersey2.version}</version>
</dependency> -->
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey2.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>2.26-b03</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.27</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-json-org</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
</dependencies>
</project>
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>OnlineOrganicMarket</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<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.oom.services</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<!-- <servlet>
<description>JAX-RS Tools Generated - Do not modify</description>
<servlet-name>JAX-RS Servlet</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/jaxrs/*</url-pattern>
</servlet-mapping> -->
</web-app>
CORS filter
package com.oom.services.filter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.server.ExtendedUriInfo;
#Provider
#Priority(Priorities.HEADER_DECORATOR)
public class CORSFilter implements ContainerRequestFilter, ContainerResponseFilter {
private static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
private static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
private static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
private static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
private static final String AUTHORIZATION = "authorization";
private static final String ORIGIN = "Origin";
private static String extractAllowedMethods(final ExtendedUriInfo extendedUriInfo) {
final Optional<Class<?>> optional = extendedUriInfo.getMatchedRuntimeResources().stream()
.flatMap(r -> r.getResources().stream()).flatMap(r -> r.getHandlerClasses().stream())
.filter(r -> r.getPackage().getName().startsWith("com.oom.services")).findFirst();
if (optional.isPresent()) {
return Arrays.stream(optional.get().getDeclaredMethods())//
.flatMap(m -> Arrays.stream(m.getAnnotations()))//
.map(a -> a.annotationType().getAnnotation(javax.ws.rs.HttpMethod.class))//
.filter(Objects::nonNull)//
.map(HttpMethod::value)//
.distinct()//
.collect(Collectors.joining(", "));
}
// Returning OPTIONS is a bit shady, as ACAM is about *real*, actual methods only.
return "OPTIONS";
}
#Context
private HttpServletRequest request;
#Context
private ExtendedUriInfo extendedUriInfo;
#Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
final String origin = requestContext.getHeaderString(ORIGIN);
if (origin != null && "OPTIONS".equals(requestContext.getMethod())) {
request.setAttribute(this.getClass().getName(), true);
requestContext.abortWith(Response.ok("CORS OK, carry on.", MediaType.TEXT_PLAIN_TYPE).build());
}
}
/**
* #see https://www.w3.org/TR/cors/
* #see https://jmchung.github.io/blog/2013/08/11/cross-domain-on-jersey-restful-web-services/
* #see https://solutionsisee.wordpress.com/2016/06/30/adding-cors-support-in-jersey-server/
*/
#Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext)
throws IOException {
final MultivaluedMap<String, Object> responseHeaders = responseContext.getHeaders();
final String origin = requestContext.getHeaderString(ORIGIN);
if (origin != null) {
// The presence of the Origin header marks a CORS request.
responseHeaders.add(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
responseHeaders.add(ACCESS_CONTROL_ALLOW_METHODS, extractAllowedMethods(extendedUriInfo));
responseHeaders.add(ACCESS_CONTROL_ALLOW_HEADERS, AUTHORIZATION + ", X-Requested-With, Content-Type");
if (requestContext.getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS) != null) {
responseHeaders.add(ACCESS_CONTROL_ALLOW_CREDENTIALS, requestContext
.getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS).toLowerCase().contains(AUTHORIZATION));
}
}
if (request.getAttribute(this.getClass().getName()) != null) {
// We are in a CORS Preflight answer, fast tracked. The entity (== response body) is not
// relevant.
}
}
}
Currently getting this error
<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Message</b> org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/filter/TokenFilter</p><p><b>Description</b> The server encountered an unexpected condition that prevented it from fulfilling the request.</p><p><b>Exception</b></p><pre>javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/filter/TokenFilter
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:432)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
</pre><p><b>Root Cause</b></p><pre>org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/filter/TokenFilter
org.glassfish.jersey.servlet.internal.ResponseWriter.rethrow(ResponseWriter.java:278)
org.glassfish.jersey.servlet.internal.ResponseWriter.failure(ResponseWriter.java:260)
org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:460)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:285)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
org.glassfish.jersey.internal.Errors.process(Errors.java:316)
org.glassfish.jersey.internal.Errors.process(Errors.java:298)
org.glassfish.jersey.internal.Errors.process(Errors.java:268)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
</pre><p><b>Root Cause</b></p><pre>java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/filter/TokenFilter
com.fasterxml.jackson.databind.ObjectMapper._newReader(ObjectMapper.java:640)
com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3323)
org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase._configForReading(ProviderBase.java:489)
org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase._endpointForReading(ProviderBase.java:882)
org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:789)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:257)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:236)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:73)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1091)
org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271)
org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:97)
org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:80)
org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.apply(ParamValueFactoryWithSource.java:74)
org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:92)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:133)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
org.glassfish.jersey.internal.Errors.process(Errors.java:316)
org.glassfish.jersey.internal.Errors.process(Errors.java:298)
org.glassfish.jersey.internal.Errors.process(Errors.java:268)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
</pre><p><b>Root Cause</b></p><pre>java.lang.ClassNotFoundException: com.fasterxml.jackson.core.filter.TokenFilter
org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1363)
org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1186)
com.fasterxml.jackson.databind.ObjectMapper._newReader(ObjectMapper.java:640)
com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3323)
org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase._configForReading(ProviderBase.java:489)
org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase._endpointForReading(ProviderBase.java:882)
org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:789)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:257)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:236)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:73)
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1091)
org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271)
org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:97)
org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:80)
org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.apply(ParamValueFactoryWithSource.java:74)
org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:92)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:133)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
org.glassfish.jersey.internal.Errors.process(Errors.java:316)
org.glassfish.jersey.internal.Errors.process(Errors.java:298)
org.glassfish.jersey.internal.Errors.process(Errors.java:268)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
</pre><p><b>Note</b> The full stack trace of the root cause is available in the server logs.</p><hr class="line" /><h3>Apache Tomcat/9.0.20</h3></body></html>
i get the error: Unable to scan WEB-INF for JAX-RS annotations, you must manually register your classes/resources
I have the following maven config:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-servlet-initializer</artifactId>
<version>3.0.4.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cdi</artifactId>
<version>3.0.4.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>2.2.14.Final</version>
</dependency>
My java class is a minimalistic call.
#Path("test")
public class MyResource {
// #Inject
// private JpaUserDao userDao;
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* #return String that will be returned as a text/plain response.
*/
#GET
#Produces(MediaType.TEXT_XML)
public String getIt() {
System.out.printf("");
return "Got it!";
}
}
I want to marry rest easy with cdi. In my web app i enabled the scan config, because i want that the annotation #path is found automatically.
My web.xml
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
</listener-class>
</listener>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
You are using restEasy 3.0.+ so use a design pattern like singleton to initiate your webservice.
#ApplicationPath("/mainPathToWebService")
public class singletonHelper extends Application {
#SuppressWarnings("unchecked")
public Set<Class<?>> getClasses() {
return new HashSet<Class<?>>(Arrays.asList(MyResource.class));
}
}
I am using Spring MVC 4.1.5 with its REST support trying to get a web service working with google protocol buffers message format. I have seen a lot of posts that are mentioning this issue with JSON format but none with google protocol buffers format.
Also I don't see Spring framework docs have a MediaType for protobufs (more on that below) My code is posted here on github
Here's my controller code (using or not using produces="application-xprotobuf" makes no difference - same 406 not acceptable error)
#RestController
#RequestMapping("/ws")
#EnableWebMvc
public class CustomerRestController {
#Autowired
private CustomerRepository customerRepository;
//#RequestMapping(value="/customers/{id}", method = RequestMethod.GET, produces="application/x-protobuf")
#RequestMapping(value="/customers/{id}", method = RequestMethod.GET)
public CustomerProtos.Customer customer(#PathVariable Integer id) {
return this.customerRepository.findById(id);
}
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
private CustomerProtos.Customer customer(int id, String f, String l, Collection<String> emails) {
String emailAddressString = "defaultEmail#address.com";
for (String email : emails) {
emailAddressString = email;
break;
}
EmailAddress emailAddress = CustomerProtos.Customer.EmailAddress.newBuilder()
.setType(CustomerProtos.Customer.EmailType.PROFESSIONAL).setEmail(emailAddressString).build();
return CustomerProtos.Customer.newBuilder().setFirstName(f).setLastName(l).setId(id).addEmail(emailAddress)
// .addAllEmail(emailAddresses)
.build();
}
#Bean
CustomerRepository customerRepository() {
return new CustomerRepositoryImpl();
}
}
here's my 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>demo</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>
<servlet-name>rest</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/rest-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Here's my pom.xml, please note that i do have google protobuf libaries added here and they do end up in WEB-INF/lib folder of the deployed .war file.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.DemoApplication</start-class>
<java.version>1.8</java.version>
<jackson.version>2.5.3</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-legacy</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here's my test client
package demo;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestTemplate;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class DemoApplicationTests {
#Configuration
public static class RestClientConfiguration {
#Bean
RestTemplate restTemplate(ProtobufHttpMessageConverter hmc) {
return new RestTemplate(Arrays.asList(hmc));
}
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
}
#Autowired
private RestTemplate restTemplate;
#Test
public void contextLoaded() {
ResponseEntity<CustomerProtos.Customer> customer = restTemplate.getForEntity(
"http://localhost:7001/demo-0.0.1-SNAPSHOT/ws/customers/2", CustomerProtos.Customer.class);
System.out.println("customer retrieved: " + customer.toString());
}
}
When I run the client from command line using mvn test
I get the following error
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.697 sec <<< FAILURE! - in demo.DemoApplicationTests
contextLoaded(demo.DemoApplicationTests) Time elapsed: 0.037 sec <<< ERROR!
org.springframework.web.client.HttpClientErrorException: 406 Not Acceptable
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:289)
at demo.DemoApplicationTests.contextLoaded(DemoApplicationTests.java:42)
I saw people suggesting using a contentNegotiationManager
In my rest-servlet.xml I have mvc:annotation-driven tag
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="demo" />
<mvc:annotation-driven />
</beans>
Also I have dropped in a webConfig.java in demo package
package demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* Total customization - see below for explanation.
*/
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.TEXT_PLAIN).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON).
mediaType("x-protobuf", MediaType.ALL)
;
}
}
I get the 406 not acceptable error with and without the webconfig.java (which is doing the work of contentNegotationManager).
I haven't been able to find a MediaType.APPLICATION_XPROTOBUF in Spring 4.1.3 or even 4.2.3 jars .
So I have left that value to MediaType.ALL ( I think that should work ?)
When I run the test client I get this message before actually running the test..
09:27:26.198 [main] DEBUG o.s.web.client.RestTemplate - Created GET request for "http://localhost:7001/demo-0.0.1-SNAPSHOT/ws/customers/2"
09:27:26.199 [main] DEBUG o.s.web.client.RestTemplate - Setting request Accept header to [application/x-protobuf, text/plain, application/xml, application/json]
09:27:26.245 [main] DEBUG o.s.web.client.RestTemplate - GET request for "http://localhost:7001/demo-0.0.1-SNAPSHOT/ws/customers/2" resulted in 406 (Not Acceptable); invoking error
handler
It clearly shows its setting the accept headers to include "application-xprotobuf" value as well.
Not sure what I am missing in this case.
I had the same issue with the controller failing with 406: Not Acceptable. After a lot of tracing I figured out the statement in the example:
Spring Boot automatically registers HttpMessageConverter beans so we need only define the ProtobufHttpMessageConverter bean and it gets configured appropriately.
is to be understood literally, since without Spring Boot no converter registration happens. The bean is instantiated, but it's never registered in the list of HttpMessageConverters.
I've solved it by explicitly registering a ProtobufHttpMessageConverter instance:
#Configuration
#EnableWebMvc
#ComponentScan
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new ProtobufHttpMessageConverter());
super.configureMessageConverters(converters);
}
}
You don't need to declare a separate bean for it (unless you plan to call it explicitly).
Also note that overriding configureMessageConverters() disables all standard converters; if you mean to extend the list of stock converters rather than replace it, override extendMessageConverters() instead.
I had written a very small rest service. When I am trying through the rest cilent, I am getting the error as "method not supported". Can anybody, please suggest me on this.
**controller class**
#Controller
#RequestMapping("/movie")
public class MovieController {
#RequestMapping(value="/{name}", method = RequestMethod.PUT, consumes="application/json")
public #ResponseBody Student getMovie(#PathVariable String name, ModelMap model, #RequestBody Student student, HttpSession session) {
Map<Integer, Student> empData = new HashMap<Integer, Student>();
empData.put(1, student);
return student;
}
}
**Request I am sending throught Rest DHC Client**
URL: http://localhost:8081/SpringMVC/movie/test
method selected: PUT
Headers: Content-Type:application/json
Body: {
"userId":"21",
"firstName":"srinu",
"lastName":"nivas"
}
I use only Jersey to do what you want.
My web.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" 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_3_0.xsd">
<display-name>appName</display-name>
<filter>
<filter-name>jersey</filter-name>
<filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.appName.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/Pages/</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(resources|(Pages))/.*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
And in the rest class i return a Viewable:
My rest class:
#GET
#Path("/PathToAccessPage")
#Produces(MediaType.TEXT_HTML)
public Viewable GetMyClassPage(#Context HttpServletRequest request, #Context UriInfo ui, #Context HttpHeaders hh) {
try {
MyClass myClass = getMyClass();
return new Viewable("/page", myClass);
}
catch (Exception ex) {
return new Viewable("/error", "Error processing request: " + ex.getMessage());
}
}
Hope you help!
Finally, I got the solution. I didn't import the below two jars.
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
As I am using spring MVC and as you can see in the above code, I am giving as consumes=application/json, I thought springMVC will take care of that. It's my mistake and also, I think the error which was renedered by spring, should be something specific to this. Anyway, got the solution. Thanks all for the help.
I'm following the tutorial here
http://jfarcand.wordpress.com/2011/06/29/rest-websocket-applications-why-not-using-the-atmosphere-framework/
I already have a Jersey project up and running and working fine using JBoss 7. The one difference i have is that i am using Jersey with Spring. So my JQueryPubSub looks like this
#Service <-- For Spring component Scan
#Path("/pubsub/{topic}")
#Produces("text/html;charset=ISO-8859-1")
public class JQueryPubSub {
#PathParam("topic")
Broadcaster topic;
#GET
public SuspendResponse<String> subscribe() {
return new SuspendResponse.SuspendResponseBuilder<String>()
.broadcaster(topic)
.outputComments(true)
.addListener(new EventsLogger())
.build();
}
#POST
#Broadcast
public Broadcastable publish(#FormParam("message") String message) {
return new Broadcastable(message, "", topic);
}
}
So i wanted to add this example but i'm getting
22:55:27,381 SEVERE [com.sun.jersey.spi.inject.Errors] (MSC service thread 1-3) The following errors and warnings have been detected with resource
and/or provider classes:
SEVERE: Missing dependency for field: org.atmosphere.cpr.Broadcaster com.order.resources.JQueryPubSub.topic
Any ideas how i can fix this issue and why Jersey seems to be aggressively injecting the value into broadcaster??
I had the same problem and was able to fix it by updating jersey jars from 1.4 to 1.6
If you use maven, you can add the following dependencies.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.6</version>
</dependency>
Answering after long time..but people who are trying can still take some advantage out of this
You can try with the following .
I just tried and it worked for me
Step-1
If you are using weblogic 12 c make the following change
function subscribe() {
var request = {
url :document.location.origin+'/<your-context-path>/ws/pubsub/' + getElementByIdValue('topic'),
Step-2
In web.xml add the below configuration
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>*******package name where your handler is**********</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
<param-value>org.atmosphere.client.TrackMessageSizeFilter
</param-value>
</init-param>
<init-param>
<param-name>WEBSOCKET_PROTOCOL_EXECUTION</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<url-pattern>/pubsub/*</url-pattern>
</servlet-mapping>
step-3
paste the below code in a java file in the package you defined in the above step(also can be found in the git site of atmosphere)
import java.io.IOException;
import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.config.service.AtmosphereHandlerService;
import org.atmosphere.config.service.Singleton;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.handler.AtmosphereHandlerAdapter;
import org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor;
import org.atmosphere.interceptor.BroadcastOnPostAtmosphereInterceptor;
import org.atmosphere.interceptor.SuspendTrackerInterceptor;
import org.atmosphere.util.SimpleBroadcaster;
#Singleton
#AtmosphereHandlerService(path = "/{chat}",
interceptors = {
AtmosphereResourceLifecycleInterceptor.class,
TrackMessageSizeInterceptor.class,
BroadcastOnPostAtmosphereInterceptor.class,
SuspendTrackerInterceptor.class},
broadcaster = SimpleBroadcaster.class)
public class AtmosphereHandler extends AtmosphereHandlerAdapter {
#Override
public void onStateChange(AtmosphereResourceEvent event) throws IOException {
if (event.isSuspended()) {
String message = event.getMessage() == null ? null : event.getMessage().toString();
if (message != null && message.indexOf("message") != -1) {
event.getResource().write(message.substring("message=".length()));
} else {
event.getResource().write("=error=");
}
}
}
}
Now deploy the ear it works..
Jar files
atmosphere-annotations-2.1.1.jar
atmosphere-jersey-2.1.1.jar
atmosphere-runtime-2.1.1.jar
atmosphere-weblogic-2.1.1.jar
commons-collections-3.2.1.jar
commons-dbutils-1.5.jar
commons-io-2.4.jar
jersey-core-1.17.1.jar
jersey-json-1.17.1.jar
jersey-server-1.17.1.jar
jersey-servlet-1.17.1.jar
log4j-1.2.15.jar