Intercept 400 response generation when Jersey detects bad xml? - jersey

I'm writing a test server that needs to emulate a 3rd party RESTful server, I'm using Jersey to write the test server.
All of the requests are POST with application/xml payloads so I started off with:
#Path("GetUserDetails")
#POST
#Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(GetUserDetailsReq request) {
...
}
Jersey happily returns 400 when the XML is badly formatted (GetUserDetailsReq is a JAXB object), which is not what I need. Rather I need to return 200 and an XML error block.
I can get around the 400 by unmarshaling in the method and using an #Provider/ExceptionMapper class, but that's clunky. Is there anyway to specify to Jersey an alternative to returning the 400 declaratively? Maybe a variant on #Provider/ExceptionMapper?
TIA.

Pavel Bucek answered this in the mailing list: http://jersey.576304.n2.nabble.com/Intercept-400-response-generation-when-Jersey-detects-bad-xml-tt7221572.html

Related

What´s the difference between HttpResponse and HttpResponseMessage?

I´m building a web application using asp.net Framework 4.8 and I´m trying to customize the response to the client when there´s an exception by creating my own Response class.
I was looking about how to implement it and I realized that there are two classes that handle the requests and responses, one of them was HttpContext.Response whose type is HttpResponse and the other was HttpResponseMessage so I was wondering, What´s the difference between them?
That can't be too easily summarized since they are two completely different classes:
You can get a bit of an idea by a quick look at their properties.
HttpResponse
https://learn.microsoft.com/en-us/dotnet/api/system.web.httpresponse?view=netframework-4.8
HttpResponseMessage
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpresponsemessage?view=net-6.0

How to consume Soap Rpc encoded in spring boot?

Hello I managed to generate classes from wsdl using axis 1.4.But I am stuck at invoking services. I tried to used WebServiceTemplate and jaxb2marshaller but there is no request class generated. So I tried created request class manually based on the generated response class. But it is getting any response from server.It says xmlrootelement is not found. So i think jaxb2marshaller is not the correct way to invoke service since it is old rpc encoded soap wsdl. Suggest me the idea to invoke service.
Update:
when using axis 1.4
I found the solution to invoke methods.It is simple 2 line code.
SomeService service=new SomeServiceLocator().getSomeServicePort();
Sample sample=service.fetchSample();

Response with non-OK status does not respect content-type in producer annotation

I encountered an odd while I was using Jersey..
I had the #Producer (MediaType.APPLICATION_JSON) for the whole resource class.
I have one class CustomerResponse, which is just normal)
If I return Response.status(Stauts.OK).entity(customerResponse).build(), on the client side, I will receive the json entity as I expected.
However, if I return Response.status(Stauts.BAD_REQUEST).entity(customerResponse).build(), the content-type become text/html.
If I change the Producer to APPLICATION_XML, the same thing happens. It seems to me that only response with 400 will return with content-type specified in the #Producer annotation. For all responses with other status code, it will simply return text/html.
Can anyone help me on this? Thank you very much.
This is turns out to be really interesting.
I started grizzly servlet instead grizzly server by using following code
WebappContext webappContext = new WebappContext("GRIZZLY Web Server WebappContext");
ServletRegistration servletRegistration = webappContext.addServlet("JerseyServletContainer", ServletContainer.class);
servletRegistration.setInitParameter("jersey.config.server.provider.packages", WebServiceConstants.ROOT_PACKAGE);
servletRegistration.addMapping("/*");
webappContext.deploy(grizzlyWebServer);
startGrizzlyWebServer(grizzlyWebServer);
It seems like the servlet somehow convert the content-type for all non-OK (not 400) http response to type=text/html; charset=ISO-8859-1.
If I started the grizzly-http-server, everything works fine.
We use like the following:
Response.status(Response.Status.BAD_REQUEST).entity(myObject)
.type(MediaType.APPLICATION_JSON_TYPE).build()

Best way to mock complex soap responses

I have a Java method I want to Unit test, but it requires a mocked SOAP response which contains multiple lists and layers of nodes. I am doing this with a handwritten mock i.e. just manually creating the objects and setting the values, but as the response is quite complex its a pain building up the response. I have a sample XML response is there an easy way of creating the mock using the XML?
Also I looked at Mockito and it looks fine for simple Objects, but it doesnt seem that good for complex responses (I may not be using it to its full potential).
The app stack is Java 1.6, Spring 3 and using JAX-WS.
I do something like this
#WebService
public class MyWebService {
#Autowired
private ServiceBean serviceBean;
public SomeReturedData getData(SomeInputData inputData) {
return serviceBean.getData(inputData);
}
}
For my UnitTest, I have a mock instanciation of "ServiceBean" which I inject in to #MyWebService, and "MyWebService" is deployed using the "in-vm" transport as described here
By Using the in-vm transport, All the XML marshalling/unmarshalling is still done by the web-service framework ,and you only have to deal with Java part.
Now someone might ask, why not test the "ServiceBean" directly, why the need to deply a WS using in-vm transport ? Well 2 things, Using in-vm transport you get to test that the JAXB XML marshalling/unmarshalling is working correctly, and it also allows you to test any intercepting handlers that you might have defined for your webservice.

JAX-RS Jersey - Howto force a Response ContentType? Overwrite content negotiation

Jersey identifies requests by looking at the accept header. I have a request which accepts only text/* - How can i force the response to be for example application/json?
#POST
#Path("/create")
#Produces(MediaType.APPLICATION_JSON)
public MyResponseObject create() {
return new MyResponseObject();
}
If a request is directed to create which only accepts text/* jersey will return a 500. Is there a way to workaround this issue? (I can't change the requests accept header).
Jersey also supports this via ResourceConfig property PROPERTY_MEDIA_TYPE_MAPPINGS that you could configure in your web.xml or programatically via Jersey APIs as shown below:
DefaultResourceConfig rc = new DefaultResourceConfig(MyResource.class);
rc.getMediaTypeMappings().put("json", MediaType.APPLICATION_JSON_TYPE);
rc.getMediaTypeMappings().put("xml", MediaType.APPLICATION_XML_TYPE);
SimpleServerFactory.create("http://localhost:9090", rc);
You can force content type negotiation by suffixing either .json or .xml to your URL.
I solved this by using a servlet filter:
http://www.zienit.nl/blog/2010/01/rest/control-jax-rs-content-negotiation-with-filters

Resources