Unable to return a JSON object using POST method
Unable to return a JSON object using POST method
I am writing a Jersey 2 Restful web service.
Here is the service class:
package com.Test.PS;
import java.io.IOException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.QueryParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import com.Test.Exchange.*; // Here class UserInfo is defined
@Path("/ps")
public class TestService
private UserInfo ui;
public TestService () throws IOException
ui = new UserInfo();
public TestService (String uid) throws IOException
UserInfo ui = ObjectFileStore.serializeDataIn(uid);
public TestService (UserInfo ui) throws IOException
this.ui = ui;
ObjectFileStore.serializeDataOut(ui);
@GET
@Produces(MediaType.TEXT_HTML)
public String sayHelloHTML(@QueryParam("uid") String uid)
String resource="<h1> Hi '" + uid + "'. </h1>";
return resource;
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public UserInfo postNK(@QueryParam("asid") String asid, UserInfo u)
return ui;
Here is the maven dependencies:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>$version.jersey</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>$version.jersey</version>
</dependency>
<!-- JSON Support (MOXy) -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>$version.jersey</version>
</dependency>
Finaly, this is my web.xml file:
<display-name>Test-PS</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Test-PS</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.Test.PS</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Test-PS</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I am getting the following error when cosuming the post method using the following code:
UserInfo n2k = new UserInfo();
ClientConfig config = new ClientConfig(MOXyJsonProvider.class);
Client client = ClientBuilder.newClient(config);
String targetUrl = "http://localhost:8081/Test-PS";
WebTarget target = client.target(targetUrl);
Invocation.Builder invocationBuilder = target.path("rest").path("ps").queryParam("asid", ASID).request(MediaType.APPLICATION_JSON);
Response response = invocationBuilder.post(Entity.entity(n2k, MediaType.APPLICATION_JSON));
UserInfo ui = response.readEntity(UserInfo.class);
response.close();
client.close();
On the console screen, I see:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/html;charset=utf-8, type=class com.Exchange.UserInfo, genericType=class com.Exchange.UserInfo.
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:232)
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.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808)
org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:321)
org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:115)
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:229)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:389)
org.glassfish.jersey.client.InboundJaxrsResponse.runInScopeIfPossible(InboundJaxrsResponse.java:264)
org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:112)
com.AS.AuthenticatorService.Authenticate(AuthenticatorService.java:79)
org.apache.jsp.JSP.Authenticate_jsp._jspService(Authenticate_jsp.java:128)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:458)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
The server logs says:
"POST /Test-PS/rest/ps?asid=AS1 HTTP/1.1" 500 1081
I have tried lots of solutions provided for this error but non of them works!!!
I want also to add that if the POST method returns a primitive type, e.g., String, instead of the user defined one, i.e., UserInfo, it works!
UserInfo is a serialized class with fields like: username, date of birth, etc..
response.readEntity(String.class)
If it is an error, check the server log, are there any exception being thrown? If not, maybe it is being swallowed up, Try registering a generic ExceptionMapper to see if you can catch the exception and print the stack trace.
– Paul Samsotha
Aug 27 at 20:19
Thank you Paul. I will do so tomorrow as I have no access to the code right now, however, I would like to say that I have already checked the server logs as I said. It seems that the correct method were called but there is an error code 500. Please check the post again to see the server logs.
– mksoi
Aug 27 at 20:29
Is the
UserInfo
class annotated with @XmlRootElement
?– Paul Samsotha
Aug 27 at 20:35
UserInfo
@XmlRootElement
No, it's just serialised. No annotations
– mksoi
Aug 27 at 20:41
2 Answers
2
You are combining to things. Your GET method can use query params but POST don't. Change your post method like this:
@POST("asid")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public UserInfo postNK(@PathParam("asid") String asid, UserInfo u)
return ui;
Then
Invocation.Builder invocationBuilder = target.path("rest").path("ps/" + ASID).request(MediaType.APPLICATION_JSON);
I used to build rest api with jax-rs so I guess there should be another way to add the ASID param.
I do not think so. Anyway I will try it. Thank you.
– mksoi
Aug 28 at 9:34
POST can use path param but not query params thats why the @POST("asid")
– Wilder Valera
Aug 28 at 13:52
As I told in my question, the code works fine if the returned class is a Java primitave class, e.g., String. So no issue with the POST accessing query params. You can try it
– mksoi
Aug 29 at 10:16
Oh, finally I got the issue. It is realy a strange one. There is a method in the UserInfo class called setUserInfo that accepts a parameter of the same class type as shown in the code bellow:
public void setUserInfo(UserInfo ui)
this.firstName = ui.getFirstName();
this.lastName = ui.getFirstName();
this.dateOfBirth = ui.getDateOfBirth();
this.homeAddress = ui.getHomeAddress();
If I delete it, everything works smoothly. Once I re-add it, I got the same exception. It seems that it is forbidden for a class to have a method which accepts a parameter of its type if this class will be sent as a Jersey JSON response.
I do not know why, but this was the issue as I tried it several times and evertime the method is added, the same exception is raised!!! It can be a bug!!!
You may try it as well
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
For som reason, you are getting back HTML (and not the JSON response) from the server. Maybe an error is occurring on the server and you are getting an error page back. Why don't you check the status code on the response. If it is not a 200, then get the String response and print it. See what it is.
response.readEntity(String.class)
– Paul Samsotha
Aug 27 at 20:16