I'm trying to do a simple REST Web Application using Tomcat 7, Apache Wink, and the Jackson JSON Processor, but seem to be hitting a wall. If I look in my web.xml file, I see:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Example Web Application</display-name>
<servlet>
<servlet-name>ExampleServlet</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.dummy.example.server.ExampleApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ExampleServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
Now, if I substitute /* for the URL pattern instead, the REST call works, but when I use /services/*, it fails.
In my ExampleApplication I see:
package com.dummy.example.server;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;
public class ExampleApplication extends Application {
/**
* Get the list of service classes provided by this JAX-RS application
*/
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> serviceClasses = new HashSet<Class<?>>();
serviceClasses.add(com.dummy.example.server.services.Employee.class);
return serviceClasses;
}
@SuppressWarnings("deprecation")
@Override
public Set<Object> getSingletons() {
Set<Object> s = new HashSet<Object>();
// Register the Jackson provider for JSON
// Make (de)serializer use a subset of JAXB and (afterwards) Jackson annotations
// See http://wiki.fasterxml.com/JacksonJAXBAnnotations for more information
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
mapper.getDeserializationConfig().setAnnotationIntrospector(pair);
mapper.getSerializationConfig().setAnnotationIntrospector(pair);
// Set up the provider
JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();
jaxbProvider.setMapper(mapper);
s.add(jaxbProvider);
return s;
}
}
And in my Employee class, I have:
package com.dummy.example.server.services;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.json.simple.JSONObject;
@Path("/services/employee")
@Produces(MediaType.APPLICATION_JSON)
@SuppressWarnings("unchecked")
public class Employee {
@GET
public JSONObject get() {
JSONObject json = new JSONObject();
json.put("Name", "Example");
return json;
}
}
Any ideas? I've been banging my head against this for some time now
The url-pattern parameter for your servlet (in the web.xml) is independent from the path you specify in your Employee class.
<servlet-mapping>
<servlet-name>ExampleServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
means your servlet listens on the /services/ sub-path.
@Path("/services/employee")
means that your REST application listens on the /services/employee "sub-sub-path".
So your webservice is exposed at localhost:8080/example/services/services/employee (the concatenation of the url-pattern and the @Path annotation).
If you want to expose it at localhost:8080/example/services/employee with the mentioned url-pattern, you need to change the Employee class needs to have:
@Path("employee")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With