I have created a rest service in Jersey which is internally using Jackson for mapping JSON to Java Object. The whole Service works on Apache tomcat but however when i deploy it on weblogic 10.2.3 it is giving the below error
java.lang.NoSuchMethodError: org.domain.pojo.CreateOutput.pcsetErrorText(Ljava/lang/String;)V
at org.domain.pojo.CreateOutput.setErrorText(CreateEVCOutput.java)
at org.domain.serviceinterface.ExceptionMapper.toResponse(ExceptionMapper.java:14)
at com.sun.jersey.spi.container.ContainerResponse.mapException(ContainerResponse.java:480)
at com.sun.jersey.spi.container.ContainerResponse.mapMappableContainerException(ContainerResponse.java:417)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1477)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:184)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3732)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2273)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
I am using Jersey 1.19 and weblogic 10.2.3 version.
Below is my service class POST method
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public CreateOutput RequestCall(Wrapper createServiceInput) {
/*
* handling all the business logic
*/
CreateOutput serviceOutput = new CreateOutput();
serviceOutput.setErrorCode("200");
logger.info("Messafe Successfully Consumed without any exception");
serviceOutput.setErrorText("Xml passed successfully");
serviceOutput.setStatus("SUCCESS");
// return HTTP response 200 in case of success
return serviceOutput;
}
and below is my exception mapper custom class to handle exception
#Provider
public class MapperException implements ExceptionMapper<Throwable> {
CreateOutput createOutput = new CreateOutput();
public Response toResponse(Throwable e) {
createOutput.setErrorText(e.getMessage());
createOutput.setErrorCode(Status.PRECONDITION_FAILED.toString());
createOutput.setStatus("failure");
return Response.status(Status.PRECONDITION_FAILED).entity(createOutput).type("application/json").build();
}
}
Thanks in advance for your help !
Related
I am trying to fetch rss feed but it is giving error when feed is accessed using org.springframework.core.io.URLResource class. I am using latest spring boot version 2.6.3. Am attaching sample code as well and GH repo.
#EnableIntegration
#Configuration
public class IntegrationRssFetch {
#Value("https://www.reutersagency.com/feed/?post_type=reuters-best")
private UrlResource urlResource;
#Value("https://www.reutersagency.com/feed/?post_type=reuters-best")
private URL url;
#Bean
public MetadataStore metadataStore() {
PropertiesPersistingMetadataStore metadataStore = new PropertiesPersistingMetadataStore();
metadataStore.setBaseDirectory("src/main/resources");
return metadataStore;
}
#Bean
public MessageChannel rssOutputChannel() {
return MessageChannels.direct("rss_feed_flow").get();
}
#Bean
public IntegrationFlow feedFlow() {
return IntegrationFlows
.from(Feed.inboundAdapter(this.urlResource, "feedTest")
.metadataStore(metadataStore()),
e -> e.poller(p -> p.fixedDelay(100)))
.channel("rss_feed_flow")
.get();
}
#Bean
public IntegrationFlow rssReadFlow() {
return IntegrationFlows
.from("rss_feed_flow")
.handle(message -> {
SyndEntry entry = (SyndEntry) message.getPayload();
System.out.println(entry.getTitle());
})
.get();
}
}
Following is stack trace of error
2022-02-23 15:46:51.181 ERROR 14352 --- [ scheduling-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessagingException: Failed to retrieve feed for 'FeedEntryMessageSource{feedUrl=null, feedResource=URL [https://www.reutersagency.com/feed/?post_type=reuters-best], metadataKey='feedTest', lastTime=-1}'; nested exception is java.io.IOException: Server returned HTTP response code: 403 for URL: https://www.reutersagency.com/feed/?post_type=reuters-best
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.getFeed(FeedEntryMessageSource.java:234)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.populateEntryList(FeedEntryMessageSource.java:201)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.doReceive(FeedEntryMessageSource.java:176)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.doReceive(FeedEntryMessageSource.java:57)
at org.springframework.integration.endpoint.AbstractMessageSource.receive(AbstractMessageSource.java:142)
at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:212)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:444)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.pollForMessage(AbstractPollingEndpoint.java:413)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.lambda$createPoller$4(AbstractPollingEndpoint.java:348)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:57)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:55)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.lambda$createPoller$5(AbstractPollingEndpoint.java:341)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: https://www.reutersagency.com/feed/?post_type=reuters-best
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at org.springframework.core.io.UrlResource.getInputStream(UrlResource.java:186)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.getFeed(FeedEntryMessageSource.java:224)
... 21 more
Link to GH https://github.com/pinkeshsagar-harptec/code-sample/tree/main/rssfeedissue
So, looks like that www.reutersagency.com doesn't like some User-Agent HTTP header values. For example it returns 403 for my default Java/1.8.0_251, but at the same time it is OK for Java/17.0.1 or Java/8, Java/20. But still doesn't work for Java/1.8 or 1.6, 1.7 etc. Java/11 is OK, too.
So, I suggest to upgrade to a newer Java anyway. Looks like Java 8 is already out of support on that RSS server.
Exception handler is returning 200 response even though I have specified it to return 500 in the handler (HttpStatus.INTERNAL_SERVER_ERROR) when encountering this exception.
I am using Spring Boot v1.5.4.RELEASE.
I am calling a Spring Boot service returning a JSON object. I am using a custom exception handler.
When an EntityNotFoundException occurs during deserialization, instead of returning 500 response, it returns 200 response and embeds the error in the body output. This is caused by a data error where a ManyToOne relationship not being found in Database because the foreign key is invalid.
Note that I am using a native query to pull the entities.
#Entity
#Table(name = "PARENT_ENTITY")
public class ParentEntity {
#JsonView({MyViews.ParentEntity.class})
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="CHILD_KEY")
protected ChildEntity childKey;
}
How can I make it so the service returns a 500 response instead of 200?
Code Example:
#ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler{
#ExceptionHandler(EntityNotFoundException.class)
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "INTERNAL_SERVER_ERROR")
protected ResponseEntity<Object> handleEntityNotFoundException(EntityNotFoundException ex) {
ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR);
apiError.setMessage(ex.getMessage());
apiError.setStackTrace(StringUtil.jsonEscapeNewlines(ExceptionUtils.getStackTrace(ex)));
return new ResponseEntity<>(apiError, apiError.getStatus())
}
}
Sample Output of Service:
Response Code: 200
Body:
[
{
"field1": "data1",
"childEntity": {
"childKey":"100100"
}
},
{
"field1":"data2"
"childEntity": {
"childKey": {
"status": "INTERNAL_SERVER_ERROR",
"message": "Could not write JSON: Unable to find com.test.entity.ChildEntity with id 123456; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unable to find com.test.entity.ChildEntity with id 123456; (through reference chain: java.util.ArrayList[40]->com.test.entity.ParentEntity[\"childKey\"])",
"stackTrace": "org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Unable to find com.test.entity.ChildEntity with id 123456 ; nested exception is com.fasterxml.jackson.databind.JsonMappingException: ... org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:299)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:106)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:231)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:174)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:113)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:751)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)
at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:137)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:460)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:120)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:217)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:81)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:220)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3456)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3422)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:323)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2280)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2196)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2174)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1632)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:256)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unable to find com.test.entity.ChildEntity with id 123456;
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:388)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:348)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:343)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:698)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:149)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:112)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:416)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1425)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:951)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:292)
... 58 more\
Caused by: javax.persistence.EntityNotFoundException: Unable to find com.test.entity.ChildEntity with id 123456;
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:144)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:242)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:159)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)
at com.test.entity.ParentEntity_$$_jvst2de_11.getChildKey(ParentEntity_$$_jvst2de_11.java)
at com.test.entity.ParentEntity.getChildKey(ParentEntity.java:887)
at sun.reflect.GeneratedMethodAccessor5472.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:664)
at com.fasterxml.jackson.databind.ser.impl.FilteredBeanPropertyWriter$SingleView.serializeAsField(FilteredBeanPropertyWriter.java:69)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690)
... 66 more\
",
"headers": null
}
#note: I did not cut this off just for this example. This is cut off in the actual json response resulting in badly formatted json.
I wonder if your request is being handled by the same exception handler.
You have set the user message to the "Data issue" but whereas your output response is showing it as null.
apiError.setUserMessage("Data issue:" + ex.getMessage());
//based on your code it should have at least "Data issue:"
"userMessage": null,
Please make sure to validate the code you have posted is being invoked as part of this request. Certainly, you can add a log message to confirm the same. If you are able to replicate the issue on local then you can keep a breakpoint and confirm if the same exception handler is invoked.
You can avoid the entity not found error by inner joining in the query. Below example uses native query format. This is more of a workaround solution, but it was sufficient to resolve my issue for my situation. I am marking as answer for now.
select pe.* from PARENT_ENTITY pe
inner join CHILD_ENTITY ce on pe.CHILD_KEY = ce.rowid_org_cust
I am new to the Spring MVC. I am using the Spring release 4.1.6 and deployed my two web applications A and B on tomcat 7 for the development environment. But in the actual production environment the application A will be deployed on weblogic and application B will be deployed on websphere. Below is the scenario occuring on the development environment.
From the Application A , I am submitting the jsp page and invoked the below method of the controller. From this method I am creating the HttpPost request and sending the RequestDetails domain object to the another controller's method using ApacheHttpClient api.This is the code from the sender's side or from Application A's controller.
#RequestMapping(value="/httprequestJinesh.cvr",method = RequestMethod.POST)
public #ResponseBody String createMediaRequest(#RequestBody RequestDetails requestDetails ,HttpServletRequest request, HttpServletResponse response ) throws Exception{
System.out.println("****************** createMediaRequest Method of the controller gets invoked 123 *****************");
if(requestDetails!=null){
System.out.println("******************* Requestdetails Is Been Object is been received ***************" + requestDetails.getRequestId());
}
//Sending the HttpPostRequest
StringBuilder url = new StringBuilder();
String serverUrl = "http://localhost:8080/raws/createMediaRequest.raws"; //get it from app_properpties table
url.append(serverUrl);
System.out.println("************** Started creating the Httpost request ********************");
final HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpClient httpClient = new DefaultHttpClient(httpParams);
HttpPost httppostRequest = new HttpPost(serverUrl);
httppostRequest.setEntity(new SerializableEntity(requestDetails,false));
System.out.println("************** Finished creating the Http Post request ********************");
System.out.println("*********** Before sending the Httppost Request ******************");
HttpResponse httpResponse = httpClient.execute(httppostRequest);
System.out.println("*********** After sending teh Httppost Request ******************");
return "SUCCESS";
}
On the receiver application's controller I am trying to deserialize the domain object received in the POST request. Both of the Application A and B have the RequestDetails class available in the workspace but in both of the case the package hierachy for the domain object is different.Say for example in Application A RequestDetails object is available in com.test and in application B it is available in the com.test123. Below is the code on the receiver application's controller.
RequestMapping(value = "/createMediaRequest.raws", method = RequestMethod.POST)
public Object createMediaRequest(HttpServletRequest request, HttpServletResponse response){
System.out.println("***************** MediaWorkflowController Received Media Request *******************");
try{
ObjectInputStream in = new ObjectInputStream(request.getInputStream());
RequestDetails requestDetails=(RequestDetails)in.readObject();
if(requestDetails!=null){
System.out.println("requestdetails object is not null *******************" + requestDetails.getRequestId());
}
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
Below is the code for the RequestDetails.java on Application A
package com.test;
public class RequestDetails implements java.io.Serializable{
String requestId;
public String getRequestId() {
return requestId;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
}
Below is the code for the RequestDetails.java on Application B
package com.test123;
public class RequestDetails implements java.io.Serializable{
String requestId;
public String getRequestId() {
return requestId;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
}
I am getting the below exception when the code for the receiver application's controller get executed.
****************** createMediaRequest Method of the controller gets invoked 123 *****************
******************* Requestdetails Is Been Object is been received ***************12345
************** Started creating the Httpost request ********************
************** Finished creating the Http Post request ********************
*********** Before sending the Httppost Request ******************
***************** MediaWorkflowController Received Media Request *******************
java.lang.ClassNotFoundException: com.test.RequestDetails
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:274)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:625)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1612)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at com.cira.raws.mediawf.api.services.controller.MediaWFController.createMediaRequest(MediaWFController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
*********** After sending teh Httppost Request ******************
As per my understanding the issue has occured while deserializing the object. If I am keeping the same package hierachy on both of the sides for the RequestDetails class the code is working fine.Is it compulsory to have the same package hierarchy for the RequestDetails domain object? If no how to resolve the issue I am facing?
To deserialise the object you need to have the same class in both instances. This includes the package name of the class.
As you have said the packages are different then the failure you are seeing is easy to understand.
My endpoint can't make sense of incoming JSON.
Here's the endpoint:
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.hibernate.Query;
import org.hibernate.Session;
import org.json.JSONObject;
...
#POST
#Path("/{department}/{team}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response handleJSON(JSONObject json , #PathParam("department") String department, #PathParam("team") String team){
MyObj myObj = new MyObj();
myObj.setDepartment(department);
myObj.setTeam(team);
myObj.setPlatform(json.optString("platform"));
saveObj(myObj);
return Response.ok(true).build();
}
I'm posting JSON containing the key/value for "platform" using Postman, with header: Content-Type as application/json
But I get this exception: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject
Looks like the problem has to do with: Illegal character at row 0 and column 1 expected { but read '-' !
But I'm pretty sure Postman should be sending valid JSON...
Here's more of the stacktrace:
09-Jul-2014 10:30:00.017 SEVERE [http-nio-8080-exec-4] com.sun.jersey.spi.container.ContainerResponse.logException Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject
at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:127)
at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:474)
at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123)
at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:744)
Caused by: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject
at com.owlike.genson.Genson.deserialize(Genson.java:391)
at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:125)
... 41 more
Caused by: com.owlike.genson.stream.JsonStreamException: Illegal character at row 0 and column 1 expected { but read '-' !
at com.owlike.genson.stream.JsonReader.newWrongTokenException(JsonReader.java:949)
at com.owlike.genson.stream.JsonReader.begin(JsonReader.java:425)
at com.owlike.genson.stream.JsonReader.beginObject(JsonReader.java:157)
at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:101)
at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:90)
at com.owlike.genson.convert.BeanViewConverter.deserialize(BeanViewConverter.java:102)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:56)
at com.owlike.genson.Genson.deserialize(Genson.java:389)
... 42 more
This might not be an ideal solution, but i do think it could work.
Hopefully you have the Jackson JSON dependency already...
you can find it here: http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
I would try the following code:
#POST
#Path("/{department}/{team}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response handleJSON(String json, #PathParam("department") String department, #PathParam("team") String team){
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readValue(json, JsonNode.class);
MyObj myObj = new MyObj();
myObj.setDepartment(department);
myObj.setTeam(team);
if (node.get("platform") != null) {
myObj.setPlatform(node.get("platform").textValue());
}
saveObj(myObj);
return Response.ok(true).build();
}
Notice that I am asking your WS Framework to just pass me the JSON as a String and just handling it myself.
Maybe its not ideal, but should work.
Cheers!
I don't know which JSON Serializer you are using but most probably this will be Jettison or Jackson. As far as I know they don't support converting an instance of org.json.JSONObject directly. The more common way is to simply use custom Java Beans:
public class Foo implements Serializable {
private String platform;
// getters + setters
}
#POST
#Path("/{department}/{team}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response handleJson(Foo foo, #PathParam("department") String department, #PathParam("team") String team) {
...
myObj.setPlatform(foo.getPlatform());
...
}
Foo should be annotated with #XmlRootElement if you are using Jettison.
If you don't want to create a custom Bean for every Entity you are expecting you can use Object, Map or String as parameter and serialize on your own:
#POST
#Path("/{department}/{team}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response handleJson(String json, #PathParam("department") String department, #PathParam("team") String team) {
...
JSONObject jsonObject = new JSONObject(json);
myObj.setPlatform(json.optString("platform"));
...
}
Last solution is implementing a MessageBodyReader which handles JSONObject. Simple example:
#Provider
public class JsonObjectReader implements MessageBodyReader<JSONObject> {
#Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return type == JSONObject.class && MediaType.APPLICATION_JSON_TYPE.equals(mediaType);
}
#Override
public JSONObject readFrom(Class<JSONObject> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
return new JSONObject(IOUtils.toString(entityStream));
}
}
You should first inspect how your request is being sent. It is probably being sent as an escaped String, instead of raw JSON.
In my case, that was what was happening when I was using a generic REST client to send requests as pure JSON Strings, as my client doesn't know the object definitions.
To prevent that, in your client, you could send a (org.codehaus.jettison.json) JSONObject instead of just a String (it has a constructor that accepts a JSON String), but that will depend on your dependencies. In my case I'm using Jersey 1.19.
Note that, depending on your classpath, (Jersey 1.19 with Genson in my case) you might also need to read the response input stream manually if you also want to read the response as a JSON String.
I'm currently trying to develop a simple proof of concept for a REST application using CXF 2.6.4. I'm taking the non-spring approach. I'm using JBoss AS 7.1.1 Final as my web server.
The following is my web service class:
package restful.webservice;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import restful.entity.ControllerVersion;
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class WebServiceRest implements WebServiceInterface
{
#Override
#POST
#GET
#Path("/getVersion")
public ControllerVersion getVersion(String deviceID, String[] macAddresses)
{
return new ControllerVersion();
}
}
ControllerVersion class:
package restful.entity;
#XmlRootElement(name = "ControllerVersion")
public class ControllerVersion {
private String version="R1.1.0.0";
public String getVersion() {
return version;
}
}
Now, when I try to make a REST call to my web service, I get the following exception on the server side:
18:51:52,913 WARNING [org.apache.cxf.jaxrs.utils.JAXRSUtils] (http--0.0.0.0-8080-1) No message body reader has been found for request class String[], ContentType : application/json.
18:51:52,927 WARNING [org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper] (http--0.0.0.0-8080-1) javax.ws.rs.WebApplicationException
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1054)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:614)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:238)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:236)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:209)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:130)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:225)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:145)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:201)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
at java.lang.Thread.run(Thread.java:662)
The libraries that I have under WEB-INF/lib are:
cxf-api-2.6.4.jar
cxf-bundle-2.6.4.jar
cxf-rt-frontend-jaxrs-2.6.4.jar
cxf-rt-frontend-jaxrs.jar
cxf-rt-transports-http-2.6.4.jar
geronimo-servlet.jar
jaxb-api-2.2.5.jar
jaxb-impl-2.2.5.1.jar
jaxb-xjc-2.2.5.1.jar
jettison-1.3.4.jar
log4j-1.2.16.jar
neethi-3.0.2.jar
xmlschema-core-2.0.3.jar
The interesting thing is that I tried to do another project, but this time in the signature of my web service method, I included a custom class. I had no problem reading the contents of the custom class' instance, nor a problem while returning it to my client.
Am I missing something?
UPDATE:
I tried to add the following to my web.xml:
<init-param>
<param-name>jaxrs.providers</param-name>
<param-value>
org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider
(writeXsiType=false)
</param-value>
</init-param>
And added the following dependencies as well:
jackson-jaxrs-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
jackson-xc-1.9.2.jar
Now I'm getting the following exception:
19:22:29,762 WARNING [org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper] (http--0.0.0.0-8080-1) javax.ws.rs.WebApplicationException: java.io.IOException: Stream closed
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:243)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:236)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:209)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:130)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:225)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:145)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:201)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:377)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:193)
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.ensureLoaded(ByteSourceBootstrapper.java:507)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.detectEncoding(ByteSourceBootstrapper.java:129)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.constructParser(ByteSourceBootstrapper.java:224)
at org.codehaus.jackson.JsonFactory._createJsonParser(JsonFactory.java:785)
at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:561)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:414)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1038)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:614)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578)
Update 2:
I tried to implement a method with a different signature, and this time, I have omitted the String array from the method:
public ControllerVersion getVersion(String deviceID)
Everything is working perfectly without the String array. What do you think I should do?
I apparently misunderstood how REST works. What I did to finally solve the problem was the following:
1- Changed my web service signature:
#POST
#Path("/getVersion")
#Produces(MediaType.APPLICATION_JSON)
#Consumes({"application/xml", "application/json", "application/x-www-form-urlencoded"})
public ControllerVersion getVersion(#FormParam("deviceID") String deviceID,#FormParam("macAddresses") String macAddresses)
2- Now, make sure that the client is sending a request with content-type (application/x-www-form-urlencoded) and that the client correctly adds form parameters same as those you defined in the #FormParam annotations.
3- Now, you can use a library such as FlexJson, to deserialize your parameters from a JSon String. For instance, I'm now sending the macAddresses as a JSon String: ["mac1","mac2"] from the client. On the server side, I convert this JSon string to a String[] using the following method:
public static String[] parseStringArrayFromJSONArray(String jsonArray)
{
String[] stringArray = null;
try
{
JSONArray array = new JSONArray(jsonArray);
if (array != null)
{
stringArray = new String[array.length()];
for (int i = 0; i < array.length(); i++)
{
stringArray[i] = array.getString(i);
}
}
} catch (Exception e)
{
stringArray = null;
}
return stringArray;
}
I hope this will help someone out there.
You're using #Consumes(MediaType.APPLICATION_JSON). You need to add jackson-core (and maybe some more jackson dependencies) for the conversion to work.
cxf uses jettison by default. Why do you have #GET and #POST annotations?
But it say's
java.io.IOException: Stream closed
So there is most likely an inputstream that isn't being shut down.