How to read JSON data in RestWebservice from AJAX request - java

I am trying to send a JSON string from a HTML page using AJAX call to a RESTWebservice. The methods in the server gets invoked however I am not able to retrieve the JSON data that I have set in the browser through AJAX call. I am usng jersy for the REST services.
Here is my HTML code.
<body>
<script type="text/javascript">
var userConfig = {};
userConfig.user = "arin_12";
userConfig.fullName = "Arindam";
var data = JSON.stringify(userConfig);
alert(data);
var req = new XMLHttpRequest();
req.open('POST', 'http://localhost:8080/LiveHive2/rest/hello', true);
req.setRequestHeader('Content-Type','application/json;charset=UTF-8');
req.onreadystatechange = function () {
if(req.readyState === 4 && req.status === 200) {
if(req.responseText) {
alert('The saving of data is ' + req.responseText);
}
}
}
req.send(data);
</script>
index page
</body>
Here is my JavaCode in RestWebservice.
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String sayJSONHello2(UserConfig uc) {
System.out.println("req" + uc);
return "{\"Name\":\"Arindam\"}";
}
Web.xml looks like this.
<servlet>
<servlet-name>JerseyRESTService</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.vogella.jersey.first</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>

So the body of the POST request will be
{
"user": "arin_12",
"fullName": "Arindam"
}
Write a Java class this JSON can be mappend to.
public class UserConfig {
private String user;
private String fullName;
// Constructor, Getter, Setter, ...
}
Then JAX-RS allows you to automatically convert the JSON to a class instance.
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String sayJSONHello2(UserConfig userConfig) {
System.out.println("got UserConfig: " + userConfig);
return "{\"Name\":\"Arindam\"}";
}
It is also possible to let JAX-RS handle the mapping of a result to JSON. Let's write a second class for the response.
public class HelloResponse {
private String name;
// Constructor, Getter, Setter, ...
}
Change your JAX-RS method to return an instance of this class.
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public HelloResponse sayJSONHello2(UserConfig userConfig) {
System.out.println("got UserConfig: " + userConfig);
return new HelloResponse(userConfig.getName());
}

Related

HTTP 403 Forbidden Jersey on Put Request

I am facing an 'HTTP 403 Forbidden' error while trying to consume PUT request of a restful resource from an angular client. I created this restful resource using jersey and I am using tomcat 7 as application server.
Here is my resource code:
#Path("/doc")
public class DocResource {
#PUT
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.APPLICATION_JSON)
#Path("file/upload")
public Response uploadFile(MultipartBody body, #QueryParam("ID") long ID) {
try {
Attachment attachment = body.getAttachment("file");
MultivaluedMap<String, String> headers = attachment.getHeaders();
String fileName = getFileName(headers);
DataHandler dataHandler = attachment.getDataHandler();
InputStream inputStream = dataHandler.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] tmp = new byte[4096];
int ret = 0;
while ((ret = inputStream.read(tmp)) > 0) {
bos.write(tmp, 0, ret);
}
// TODO - Save contents as process attachment
byte[] contents = bos.toByteArray();
return Response.ok(getDocumentService().createAttachment(ID, fileName, contents, attachment.getContentType()), MediaType.APPLICATION_JSON).build();
} catch (Exception e) {
return handleException(e, "failed to upload Attachement");
}
}
}
Here is my angular js snippet
this.uploadFile = function uploadFile(callback, ID, file) {
var baseRestURL="http://localhost:8080/rest/doc"
// resource query
var query ;
// create form data
var formData = new FormData();
formData.append('file', file);
// set up the resource
var resource = $resource(baseRestURL + '/file/upload', {
ID: ID
}, {
'ID': ID,
'upload': {
method: 'PUT',
headers: {
'Content-Type': 'multipart/form-data'
}
}
});
resource.upload(query, formData).$promise.then(function success(response) {
if (callback) callback(response);
}, function error() {
//TODO handle error
});
};
I want to notice that other type of http calls such as DELETE, POST and GET are working properly. I have only problems with PUT calls.
I had a similar issue, but both DELETE and PUT were not working for me - returned HTTP 403 error. After I searched I stumbled across this link, and it pointed out where I went wrong.
I had a CORS filter added in my web.xml as part of some other R&D i was doing, and forgot to remove it.
This was from the original web.xml
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
io.swagger.jaxrs.listing,
com.xxx.yyy.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
org.glassfish.jersey.jackson.JacksonFeature;
org.apache.catalina.filters.CorsFilter
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Once I removed the org.apache.catalina.filters.CorsFilter it started to work for me!
Hope this helps!

Restlet 1.1 Access Control Header Issue

I'm working on a restlet built on restlet 1.1.1
The issue I'm facing is setting the 'Access-Control-Allow-Origin' header to allow for cross domain requests. I've attempted a few things that didn't work.
Method one, put the header in the acceptRepresentation function:
#Override
public void acceptRepresentation( Representation resetEntity ) {
Form headers = (Form)getResponse().getAttributes().get("org.restlet.http.headers");
if (headers == null) {
headers = new Form();
getResponse().getAttributes().put("org.restlet.http.headers", headers);
}
headers.add("Access-Control-Allow-Origin","https://origin.server.edu");
//other code here for actual resource logic...
}
This didn't work. I still received errors when attempting to send a request using JQuery as such:
jQuery.ajax({
type: "POST",
contentType: "application/json",
url: "https://test.servername.edu/cas/cas-rest-api/reset/",
data: JSON.stringify("{\"uname\" : \"someone\", \"attr\":\"dataElement\" }"),
dataType: "json",
crossDomain: true
})
.done(function(data){
console.log("Success");
alert(data);
})
.fail(function(data){
console.log("failure");
console.log(data);
alert(data);
});
This didn't work. So I noticed an init function in the resource class. I figured I'd attempt putting my code there to see if this would change the situation.
#Override
public void init(Context context, Request request, Response response ){
Form headers = (Form)response.getAttributes().get("org.restlet.http.headers");
if (headers == null) {
headers = new Form();
response.getAttributes().put("org.restlet.http.headers", headers);
}
headers.add("Access-Control-Allow-Origin","https://origin.server.edu");
super.init(context, request, response);
}
Nope. Didn't work either. What am I missing here? Where do I set this header?
Thanks for your replies. After some analysis of the problem it turned out that I needed to configure Spring to allow option requests for my restlet in the web.xml file as shown below:
<servlet>
<servlet-name>ccrest</servlet-name>
<servlet-class>com.noelios.restlet.ext.spring.RestletFrameworkServlet</servlet-class>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>

DeferredResult with ajax request with two request

I´m trying to use DeferredResult with an ajax request, but when I return the result my ajax request keeps waiting for response.
Here the client that make the long polling request
(function poll() {
var SUCCESS = 1;
var tenantName = $("#tenantName").val();
$.ajax({
method: "GET",
url: "url.do?subStep=" + subStep + "&tenantId=" + tenantName,
success: function (response) {
alert(response)
if (response.status === SUCCESS) {
bootbox.dialog({
size:"small",
message: "<div class='col-xs-offset-4'>" +
"<i class='fa fa-user'> Page has been modify by " + response.payload + " " +
"<a href='javascript:void(0)' onclick='reload()'>reload</a>" +
"</i>" +
"</div>"
});
}
}, dataType: "json", complete: poll, timeout: 60000
});
})();
Here my controller where I make a long polling request by Ajax every 30 seconds.
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public DeferredResult<JsonEntity> getSubStepStatus(#RequestParam("subStep") String subStep,
#RequestParam("tenantId") String tenantId) {
if (tenantsInStep.get(subStep) == null) {
initializeTenantsInStep(subStep);
}
if(!tenantsInStep.get(subStep).contains(tenantId)){
tenantsInStep.get(subStep).add(tenantId);
}
DeferredResult<JsonEntity> deferredResult = new DeferredResult<>();
tenantsDeferredInStep.put(tenantId, deferredResult);
return deferredResult;
}
And then when my application detect a POST/PUT ajax request invoke a request to this method of my controller that release the DeferredResults.
#RequestMapping(value = "/setModification", method = RequestMethod.GET)
#ResponseBody
public final Integer setModification(#RequestParam("subStep") String subStep,
#RequestParam("tenantId") String tenantId) {
for (String tenantInStepId : tenantsInStep.get(subStep)) {
if (!tenantId.equals(tenantInStepId)) {
JsonEntity<String> jsonEntity = new JsonEntity();
jsonEntity.setPayload(tenantId);
jsonEntity.setStatus(FeedbackActions.SUCCESS.getCode());
DeferredResult<JsonEntity> jsonEntityDeferredResult = tenantsDeferredInStep.get(tenantId);
tenantsInStep.remove(tenantInStepId);
jsonEntityDeferredResult.setResult(jsonEntity);
}
}
return FeedbackActions.SUCCESS.getCode();
}
This example has been done by two user with two browser to achieve this, but the first client that create the deferredResult dont receive the result when the second client invoke the deferredResult.setResult(bla), no alert on ajax code is invoked.
I´m doing something wrong?, I add the
<task:annotation-driven/>
And the
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
In my applicationContext and web.xml configuration
As an extra information I´m using on my local test Jetty
Regards.

How to get form parameters in request filter

I'm trying to get the form parameters of a request in a request filter:
#Override
public ContainerRequest filter(final ContainerRequest request) {
final Form formParameters = request.getFormParameters();
//logic
return request;
}
However, the form always seems to be empty. The HttpRequestContext.getFormParameters() documentation says:
Get the form parameters of the request entity.
This method will ensure that the request entity is buffered such that it may be consumed by the applicaton.
Returns:
the form parameters, if there is a request entity and the content type is "application/x-www-form-urlencoded", otherwise an instance containing no parameters will be returned.
My resource is annotated with #Consumes("application/x-www-form-urlencoded"), although it won't have been matched until after the request filter - is that why this isn't working?
I tried doing some research but couldn't find any conclusive evidence of whether this is possible. There was this 4-year old discussion, in which Paul Sandoz says:
If you are working in Jersey filters or with the HttpRequestContext you can get the form parameters as follows: [broken link to Jersey 1.1.1 HttpRequestContext.getFormParameters]
I also found this 3-year-old discussion about how to get multipart/form-data form fields in a request filter. In it, Paul Sandoz uses the following code:
// Buffer
InputStream in = request.getEntityInputStream();
if (in.getClass() != ByteArrayInputStream.class) {
// Buffer input
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ReaderWriter.writeTo(in, baos);
} catch (IOException ex) {
throw new ContainerException(ex);
}
in = new ByteArrayInputStream(baos.toByteArray());
request.setEntityInputStream(in);
}
// Read entity
FormDataMultiPart multiPart = request.getEntity(FormDataMultiPart.class);
I tried emulating that approach for Form instead, but the result of request.getEntityInputStream() is always an empty stream. And looking at the source of getFormParameters, that method is in fact doing the same thing already:
#Override
public Form getFormParameters() {
if (MediaTypes.typeEquals(MediaType.APPLICATION_FORM_URLENCODED_TYPE, getMediaType())) {
InputStream in = getEntityInputStream();
if (in.getClass() != ByteArrayInputStream.class) {
// Buffer input
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
ReaderWriter.writeTo(in, byteArrayOutputStream);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
in = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
setEntityInputStream(in);
}
ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream) in;
Form f = getEntity(Form.class);
byteArrayInputStream.reset();
return f;
} else {
return new Form();
}
}
I can't figure out what's slurping up the entity input stream before I get to it. Something in Jersey must be consuming it because the form params are later passed into the resource method. What am I doing wrong here, or is this impossible (and why)?
EDIT: Here's an example of a request being sent:
POST /test/post-stuff HTTP/1.1
Host: local.my.application.com:8443
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
form_param_1=foo&form_param_2=bar
Here's the (somewhat redundant) request logging:
INFO: 1 * Server in-bound request
1 > POST https://local.my.application.com:8443/test/post-stuff
1 > host: local.my.application.com:8443
1 > connection: keep-alive
1 > content-length: 33
1 > cache-control: no-cache
1 > origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
1 > user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
1 > content-type: application/x-www-form-urlencoded
1 > accept: */*
1 > accept-encoding: gzip,deflate,sdch
1 > accept-language: en-US,en;q=0.8
1 > cookie: [omitted]
1 >
Here are the response headers of that request, including the Jersey Trace:
Content-Type →application/json;charset=UTF-8
Date →Fri, 09 Aug 2013 18:00:17 GMT
Location →https://local.my.application.com:8443/test/post-stuff/
Server →Apache-Coyote/1.1
Transfer-Encoding →chunked
X-Jersey-Trace-000 →accept root resource classes: "/post-stuff"
X-Jersey-Trace-001 →match path "/post-stuff" -> "/post\-stuff(/.*)?", [...], "(/.*)?"
X-Jersey-Trace-002 →accept right hand path java.util.regex.Matcher[pattern=/post\-stuff(/.*)? region=0,11 lastmatch=/post-stuff]: "/post-stuff" -> "/post-stuff" : ""
X-Jersey-Trace-003 →accept resource: "post-stuff" -> #Path("/post-stuff") com.application.my.jersey.resource.TestResource#7612e9d2
X-Jersey-Trace-004 →match path "" -> ""
X-Jersey-Trace-005 →accept resource methods: "post-stuff", POST -> com.application.my.jersey.resource.TestResource#7612e9d2
X-Jersey-Trace-006 →matched resource method: public javax.ws.rs.core.Response com.application.my.jersey.resource.TestResource.execute(java.lang.String,java.lang.String)
X-Jersey-Trace-007 →matched message body reader: class com.sun.jersey.api.representation.Form, "application/x-www-form-urlencoded" -> com.sun.jersey.core.impl.provider.entity.FormProvider#b98df1f
X-Jersey-Trace-008 →matched message body writer: java.lang.String#f62, "application/json" -> com.sun.jersey.core.impl.provider.entity.StringProvider#1c5ddffa
Here is the (unremarkable) servlet config:
<servlet>
<servlet-name>jersey</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.application.my.jersey</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>com.application.my.jersey.MyFilterFactory</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.Trace</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Here's the example resource:
#Path("/post-stuff")
#Produces(MediaType.APPLICATION_JSON)
public final class TestResource {
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response execute(
#FormParam("form_param_1") final String formParam1,
#FormParam("form_param_2") final String formParam2
) {
return Response.created(URI.create("/")).entity("{}").build();
}
}
I'm using Jersey 1.17.
For those interested, I'm trying to roll my own required parameter validation, as described in JERSEY-351. My solution here worked for query, cookie, and header params - form params are holding out on me.
This was a tricky one. I'd removed other Jersey filters to eliminate them from the problem, but missed a plain servlet filter hiding at the bottom of web.xml:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.application.my.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Removing this filter fixed the issue - form params showed up in the Jersey filter. But why? I dug deeper, narrowing down the problem to a single statement in MyFilter:
request.getParameter("some_param")
I tried to simplify the problem even more by removing MyFilter and making the same call in the Jersey filter (by injecting HttpServletRequest) - but the form parameters still showed up. The issue appears to happen specifically when calling getParameter on the org.apache.catalina.connector.RequestFacade instance that gets passed into javax.servlet.Filter.doFilter. So is this in fact a Tomcat bug?
The documentation of ServletRequest.getParameter says:
If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then reading the body directly via getInputStream() or getReader() can interfere with the execution of this method.
So maybe the reverse is true too - that calling getParameter might be allowed to interfere with the entity input stream? It's unclear to me whether the method's contract allows for this behavior, and whether it indicates a bug in Tomcat, Jersey, or neither.
Anyway, that old filter wasn't actually needed so my issue is solved but just removing it.
Here's a full reproduction of the problem (Tomcat 7.0):
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_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>test</display-name>
<servlet>
<servlet-name>jersey</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.application.my</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
<param-value>com.application.my.TestFilterFactory</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.Trace</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>servletFilter</filter-name>
<filter-class>com.application.my.TestServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>servletFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
TestServletFilter.java:
package com.application.my;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public final class TestServletFilter implements Filter {
#Override
public void init(FilterConfig config) { }
#Override
public void doFilter(
final ServletRequest request,
final ServletResponse response,
final FilterChain chain
) throws IOException, ServletException {
System.out.println("calling getParameter on " + request.getClass().getName());
request.getParameter("blah");
chain.doFilter(request, response);
}
#Override
public void destroy() { }
}
TestFilterFactory.java:
package com.application.my;
import java.util.Collections;
import java.util.List;
import com.sun.jersey.api.model.AbstractMethod;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import com.sun.jersey.spi.container.ContainerResponseFilter;
import com.sun.jersey.spi.container.ResourceFilter;
import com.sun.jersey.spi.container.ResourceFilterFactory;
public final class TestFilterFactory implements ResourceFilterFactory {
#Override
public List<ResourceFilter> create(final AbstractMethod method) {
return Collections.<ResourceFilter>singletonList(new ResourceFilter() {
#Override
public ContainerRequestFilter getRequestFilter() {
return new ContainerRequestFilter() {
#Override
public ContainerRequest filter(final ContainerRequest request) {
System.out.println("form: " + request.getFormParameters());
return request;
}
};
}
#Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
});
}
}
TestResource.java:
package com.application.my;
import java.net.URI;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/post-stuff")
#Produces(MediaType.APPLICATION_JSON)
public final class TestResource {
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response execute(
#FormParam("form_param_1") final String formParam1,
#FormParam("form_param_2") final String formParam2
) {
System.out.println("form param_1: " + formParam1);
System.out.println("form param_2: " + formParam2);
return Response.created(URI.create("/")).entity("{}").build();
}
}
Make sure your ResourceFilterFactory creates an instance of ResourceFilter for the TestResource#execute method, which then creates a ContainerRequestFilter instance:
public class MyFilterFactory implements ResourceFilterFactory {
#Override
public List<ResourceFilter> create(final AbstractMethod am) {
return new ArrayList<ResourceFilter>() {{
add(new ResourceFilter() {
#Override
public ContainerRequestFilter getRequestFilter() {
return new ContainerRequestFilter() {
#Override
public ContainerRequest filter(final ContainerRequest request) {
System.out.println(request.getFormParameters());
return request;
}
};
}
#Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
});
}};
}
}
From the trace you have provided I am not sure whether your ContainerRequestFilter is called. There should be one more trace header containing something like this:
→matched message body reader: class com.sun.jersey.api.representation.Form, "application/x-www-form-urlencoded" -> com.sun.jersey.core.impl.provider.entity.FormProvider#b98df1f
The whole trace from my test:
HTTP/1.1 201 Created
Location: http://localhost:8080/helloworld-webapp/helloworld/
Content-Type: text/plain
X-Jersey-Trace-000: accept root resource classes: "/helloworld"
X-Jersey-Trace-001: match path "/helloworld" -> "/application\.wadl(/.*)?", "/helloworld(/.*)?"
X-Jersey-Trace-002: accept right hand path java.util.regex.Matcher[pattern=/helloworld(/.*)? region=0,11 lastmatch=/helloworld]: "/helloworld" -> "/helloworld" : ""
X-Jersey-Trace-003: accept resource: "helloworld" -> #Path("/helloworld") com.sun.jersey.samples.helloworld.resources.HelloWorldResource#7449df0f
X-Jersey-Trace-004: match path "" -> ""
X-Jersey-Trace-005: accept resource methods: "helloworld", POST -> com.sun.jersey.samples.helloworld.resources.HelloWorldResource#7449df0f
X-Jersey-Trace-006: matched resource method: public javax.ws.rs.core.Response com.sun.jersey.samples.helloworld.resources.HelloWorldResource.execute(java.lang.String,java.lang.String)
X-Jersey-Trace-007: matched message body reader: class com.sun.jersey.api.representation.Form, "application/x-www-form-urlencoded" -> com.sun.jersey.core.impl.provider.entity.FormProvider#6bc1b916
X-Jersey-Trace-008: matched message body reader: class com.sun.jersey.api.representation.Form, "application/x-www-form-urlencoded" -> com.sun.jersey.core.impl.provider.entity.FormProvider#6bc1b916
X-Jersey-Trace-009: matched message body writer: java.lang.String#f62, "text/plain" -> com.sun.jersey.core.impl.provider.entity.StringProvider#4aae6c4e
Transfer-Encoding: chunked
Server: Jetty(6.1.24)
EDIT 1:
Enable request LoggingFilter:
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>
EDIT 2:
Also make sure no other Servlet or Jersey filter has read the InputStream before. In such a case the entity input stream may no longer be available (but you can still inject #FormParam into your resource method - as in this case).

Newbie Java EE, Json webservice getting a HTTP 404, using Jersey SDK

Just started to write my JSON webservices for a carpool engine. I am getting a HTTP 404 error as I try to write my registration API's.
This is where my problem is
"http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Registration"
HTTP/1.1 405 Method Not Allowed
"http://localhost:8081/mCruiseOnCarPool4All/carpool4all/Registration/Request"
HTTP/1.1 500 Internal Server Error
"http://localhost:8081/mCruiseOnCarPool4All/Registration/Request"
HTTP/1.1 404 Not Found
"http://localhost:8081/mCruiseOnCarPool4All/Registration"
HTTP/1.1 404 Not Found
I know I am missing something really silly here.
Web.xml (Jersey Library)
<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.mcruiseon.carpool4all</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/carpool4all/*</url-pattern>
RegistrationService.java, only coded the Post method. I am returning errors on all exceptions and ok with sessionkey when successful. You can ignore the code in the post method, I just wanted to share so that you understand my error handling.
package com.mcruiseon.carpool4all;
#Path("/Registration")
public class RegistrationService {
private ClientSession clientSession ;
private String sessionKey ;
private SessionManager sessionManager ;
#Context
UriInfo uriInfo;
#Context
Request request;
#POST
#Path ("Request")
#Consumes({ MediaType.APPLICATION_JSON })
public Response post(JAXBElement<AMessageStrategy> element) {
try {
clientSession = new ClientSession(God.mCruiseOnServer) ;
} catch (InvalidServerDNSorIPException e) {
e.printStackTrace();
return Response.serverError().build() ;
}
sessionKey = sessionManager.setClientSession(clientSession) ;
clientSession.setSessionKey(sessionKey) ;
clientSession.getSendQueue().sendRequest(element.getValue()) ;
try {
clientSession.waitAndGetResponse(element.getValue()) ;
} catch (WaitedLongEnoughException e) {
return Response.serverError().build() ;
} catch (UnableToResolveResponseException e) {
return Response.serverError().build() ;
}
return Response.ok(sessionKey).build();
}
}
Junit test case (removed all the HttpConnection code)
ClientIdentityConcrete clientIdentity = new ClientIdentityConcrete("username", "password", "secretkey") ;
RegistrationRequest register = new RegistrationRequest(clientIdentity);
String jsonStr = mapper.writeValueAsString(clientIdentity);
HttpPost request = new HttpPost("http://localhost:8081/mCruiseOnCarPool4All/Registration/Request");
The relevant connection is /mCruiseOnCarPool4All/carpool4all/Registration/Request
and it return a 500 error so you must have an error stacktrace on your server console.
The other URLs that you're showing are hitting 404 cause the URLs are not pointing to your Jersey servlet which seemed to be mapped to /carpool4all
Your URL pattern is :
<host>/<app>/<jerseyservlet>/<xml resource>/<method path>
with
- host = localhost:8081/ (obviously)
- app = mCruiseOnCarPool4All
- jerseyservlet = carpool4all
- xml resource = Registration
- method path = Request

Categories