How to set an HTTP error code in JAX-RS - java

I have a web service using jar-rs. How do I throw a custom http error code to the calling application?
Thanks

The Response class lets you create a response with a specific HTTP Status. You can also extend WebApplicationException.
There are a couple of examples in the JAX-RS 1.0 features overview docs, in the 'Building Responses' and 'WebApplicationException and mapping Exceptions to Responses' sections that will tell you all you need to know to get started.

Related

Transforming CXF SOAP web-service into a custom HTTP / JSON web-service

I have created a SOAP web-service, running in a tomcat container, using CXF and a WSDL contract approach. The Java code was generated from the WSDL using the maven plugin "cxf-codegen-plugin".
Now, I would like to also expose the web-service as a custom HTTP / JSON web-service by mapping the XML data into JSON data. But I haven't been successful yet and I would appreciate any help to achieve that.
I found that old documentation https://cxf.apache.org/docs/json-support.html on CXF's website (which has also been recently duplicated and not corrected here https://cwiki.apache.org/confluence/display/CXF20DOC/JSON+Support). I got it running with a small fix : sf.setBindingId(HTTPBinding.HTTP_BINDING); instead of sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID); since HttpBindingFactory does not exist anymore in CXF 3.x versions.
The first issue with that solution is that it depends on jettison-json whose last release was published in July 2016. The project looks dead. I could not find any suitable replacement. I only found StAXON which is worst : last release in February 2014.
Is there any other library that is well maintained and that implements StAX ?
The second issue is that the example uses a server bean while I already have a container. For the SOAP service, I simply use the public static Endpoint publish(String address, Object implementor) function.
How can I use both the Tomcat container and the JSON/XML conversion ?
The third issue is that I could not send a valid JSON request so far. The absence of documentation does not help. Still, I managed to get as far as sending a valid JSON equivalent of the SOAP header content. But I could not manage to guess how to make CXF also reads the equivalent of the SOAP body. The Java interface of the web-service is public Response get(Header header, Body body); and I keep getting errors : org.apache.cxf.interceptor.Fault: wrong number of arguments while invoking public abstract Response ServicePort.get(Header,Body) with params [Header#88f6973[user=bbcc2545-27ea-43cd-a1fe-c4a194258e0f]]. Obviously the body is missing.
Is there anyone who knows the right JSON syntax to send a request to a CXF HTTP / JSON web-service that relies on jettison-json ? (Or where could one find a comprehensive documentation ?)

Using Spring Boot, how to separately handle exception between normal request and ajax request

I am implementing Java web application using Spring MVC and Spring Boot.
I would like to create a custom error page (For 404, 500 errors), I try to use the solution from here:
https://stackoverflow.com/a/27393578/2148445
and it works fine. However, it intercepts all the 404/500 errors even my ajax request. My web application is based on ajax request, so when I call API, it returns custom error page instead of json response.
I would like to:
when normal request >> go to custom error page.
when ajax request >> return error response as json object.
I try to find the other ways but I cannot get the good solution so far.
I tried to use #ExceptionHandler, but my colleague said that it will override Spring boot's.
Is there a way to solve this issue?
Thank you for your help.
A solution would be to send an "X-REQUESTED-WITH" header with value "XMLHttpRequest" when doing ajax calls from the browser.
On the backend side, you can check if this header with the given value is available to decide whether it was an ajax call or not.

How to get XML file from Java Request object before sending. Web services SOAP

I am building Java application for Online Web Services and let's call it application A . I got the WSDL file form the second party so I can communicate with their application and let's call it application B.
From the WSDL file I generate the Java classes needed which are Requests and Responses classes. Application A will send some request object after setting the needed parameters and excepting response object from application B.
The connection is established and both applications A and B are communicating with each other.
Question:
From application A how can I get the xml data(file or text) for the request object before sending it to application B?
As described the connection is done by passing Java object as request and I know that in some point this request will be converted to xml file. How to get it?
--- EDIT ----
Important Information is missing that may cause confusion.
I am generated the Java Classed have been generated using Axis framework
I don't have much reputation to post a comment, so here is my answer: If you aren't yet using some framework use Apache CXF, If you want to capture the request before sending it application , you can either use cxf interceptors there are some inbuilt interceptors which can do this or you can create a custom interceptor with correct phase ( e.g. post marshal)
The problem is solved by adding the following statements in the bindingStub class that has been auto generated from the WSDL file for the web-services you are trying to access.
String request = _call.getMessageContext().getRequestMessage().getSOAPPartAsString();
String response = _call.getMessageContext().getResponseMessage().getSOAPPartAsString();
These statements should be placed after the following method call _call.invoke otherwise you will get NullPointerException .
_call is a variable of type org.apache.axis.client.Cal and it is auto generated by Axis

How to propagate CXF exceptions from server to client

I have a WSDL First Apache CXF web service that works as expected, except that the exceptions that I throw on the server side are not received as such on the client.
Instead on the client side I get an exception of type SOAPFaultException in which only the detailMessage contains the message from the original server side Exception, but I'd like to receive the exact exception type I threw on the server side, including the cause chain.
I expected this to work like this by default, but it certainly doesn't in my system. I have been checking the CXF documentation to find hints about how to achieve this, but so far I haven't found anything useful.
The SOAP reference does not support stacktrace. If you want that you will need to copy the stacktrace as the message returned by the SoapFault.
With CXF you can do it by add a Interceptor on the income interceptor chain. Please refer to this question to see how to create a interceptor.
You should put it on the POST_INVOKE Phase.

Java Web Service HttpServletRequestWrapper Issue: IllegalStateException

I am currently developing a RESTful Webservice in Java using the Jersey library.
For security reasons, we want a custom authentication similar to Amazons Simple Storage Service. This requires, however, that I calculate an MD5 hash of the body (if there is any) to authenticate the request.
So far, I have used a custom Authenticator and Realm and plugged them into my context.
Upon trying to calculate the hash I first used the request itself resulting in an IllegalStateException, since the body can only be read once.
After investigating the problem I tried to wrap the request inside a HttpServletRequestWrapper but hasn't been successful so far.
I am basically using a wrapper like the one shown here:
http://forums.oracle.com/forums/thread.jspa?threadID=2156814&tstart=0
Inside my realm, where I do the authentication, I am first creating the wrapper like so:
MyRequestWrapper requestWrapper = new MyRequestWrapper(request);
then I am calculating the MD5 using the requestWrapper
and finally forwarding it
request.getRequestDispatcher("/*").forward(requestWrapper, response);
The processing works fine but I get an error like this after that:
Servlet.service() for servlet Jersey REST Service threw exception
java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:407)
at com.sun.jersey.spi.container.servlet.WebComponent$Writer.finish(WebComponent.java:285)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:241)
Note that there is no mentioning of the getReader or getInputStream being called before (like I got without using any wrapper at all).
Now I am sure I am doing something wrong here but I really don't know much about this and would be really glad if someone could help me out here :)
Best Regards,
Lukas
As stated in my comment to my question:
I was accessing getReader() from the request. Response I did not touch. However I found that the problem was forwarding the wrapper. I didn't explicitly state this in my question but I am using tomcat and tried to use the above code inside a valve. I am still interested in the question if this is also possible from a valve, since this fits better into the tomcat model. I have now moved to using a filter which is not so nice, but works
I found however that this solution is quite nice (using a filter) instead of a tomcat valve.

Categories