Pass object as arument in RESTful web service - java

I am creating a simple RESTful web service with simple types successfully. Now I want to pass an object as argument for web service and get the object as response. My scenario is, Parse the XML message as object by using Jaxb and send the object as request for web service. After that in server side it process the requested object and generates the response xml file and send back it as object.
In URL path i give
"http://localhost:8080/SampleWS/rest/checkXML/username=visolve&password=visolve"
for simple type. But in object I don't know how to give the object reference in URL. Please help me how to solve my problem..
Regards
Bathakarai

Just define a very good-looking domain object. JAXB and JAX-RS will do the rest.
JAXB.
#XmlRootElement
class Regards {
#XmlElement
private long sincerely;
}
JAX-RS.
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#POST
#Path("/sincerely")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response sincerely(final Regards regards) {
regards.setSincerely(System.currentTimeMillis());
return Response.ok(regards).build();
}

Though you could certainly include the entire XML content in your URL, I would probably shy away from it.
Think of it this way: if you encode the XML in the URL you're potentially adding more work on both ends. Now the server and client will both need to know how to build the URL properly, and check to make sure everything lines up correctly. What if, in the future, you need to offer a JSON or YAML view of the same content? Now your URL might need to include the content-type as well. What about character-encoding?
All this to say, HTTP provides a terrific transport mechanism which already addresses these concerns. Include the XML as the entity body of the HTTP message, and use the HTTP header to identify what content-type you're sending, character-encoding, etc. This will work both ways (the server and client both can send the XML back/forth), and makes better use of HTTP.
Here's a related link which might help with some of the details. And another.
On a side note, please, please, please tell me you don't plan on sending user-credentials in plain text across an unencrypted link.

Related

Application/JSON is Unsupported Media Type in restful webservice

I am trying to create a restful-jersey webservice. I have to pass JSON object to the webservice.
#POST
#Path("/saveVehicleTrackingData")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.TEXT_PLAIN)
public String saveVehicleTrackingData(VehicleTracking vehicleTracking) {
return vehicleTracking.toString();
}
When I try try to make request to the service, it says HTTP Status 415 - Unsupported Media Type. Please help. Also, what should be the type of single argument of the method saveVehicleTrackingData.
PS: I am using POSTMAN to make http request. http://goo.gl/vwXNXQ
UPDATE :
As pointed out by peeskillet, the missing thing here is JSON Provider. The next challenge that I have is, how to integrate the JSON Provider in my project. After researching a little, I found FasterXML jackson as one of the JSON provider.
This image is just for reference. I just had it from another post.
Basically when you use raw, it will default to text/plain. The JSON in the drop down, is simply to select syntax highlighting. You still need to set the Content-Type header to application/json. You can click on the Headers button and add it.
For your first question:
What kind of hosting (Tomcat, GlassFish or whatever...) are you using, and what is the Java version of the host? I know from experience that different version of Tomcat in combination with Jersey sometimes gives problems with #Consumes(MediaType.APPLICATION_JSON).
About your second question:
You want to build a RESTful webservice, the right name for a path should be; VehicleTrackingData (or whatever you like). This path will work (request/response) with the known HTTP verbs; GET, POST, PUT or DELETE.

How do I store SOAP responses in the database securely?

I am working on an internal tool that simulates SOAP responses for different web services that our product uses. This is intended for use in local development.
The idea is to store the SOAP responses in the database as a blob data. During the mapping of a URL keys to a response, the URL keys and expected SOAP response will be stored to the database. The simulated SOAP response will be as a string body in POST request.
The SOAP response will be stored as a blob in the database along with URL keys. If the URL is /configureresponse/{responsetype}/{responsecode}/, then the values of response type and response code will be saved to the database along with the SOAP response as string.
I am building a Spring MVC application for the same. The code snippet is given below
#Controller
#RequestMapping(value = "/configureresponse/{responsetype}/{responsecode}",
method = RequestMethod.POST)
public ModelAndView configureResponse(
#PathVariable String responseType, #PathVariable String responseCode,
#RequestBody String soapResponse) {
}
How do I return a Servlet Response such as 200 OK or 403 Forbidden based on certain conditions?
Is there a way to secure the incoming XML response and the outgoing XML response? This is an internal tool, but I am not sure how to handle XML injection or any other security issues.
UPDATE: How do I secure the application against a billion laughs attack or make it more secure?
Should I be checking for XSRF vulnerability? If yes, how do I do that?
How do I handle simultaneous concurrent inputs for the same response and request?
UPDATE: How do I check if say one thread is updating the response for a given response type and response code, while the other thread is viewing the response for a given response type and response code?
How do I return a Servlet Response such as 200 OK or 403 Forbidden based on certain conditions?
There are several ways to do this. For instance, you could change your return type to a ResponseEntity<String>, which has a constructor that accepts an HttpStatus. Or, you could simply pass in an HttpServletResponse and set the response code there. Knowing Spring, there are probably 20 more valid ways to do this. I would suggest reading through the excellent Reference Guide available on their site.
Is there a way to secure the incoming XML response and the outgoing XML response? This is an internal tool, but I am not sure how to handle XML injection or any other security issues.
Not sure what you mean by "secure". If you mean transmission, then use SSL. If you mean authorization/authentication use Spring Security. If you mean something else, then I am not sure what to offer except to say I need a better explanation of what you want/need.
Should I be checking for XSRF vulnerability? If yes, how do I do that? Any link or tutorial would be welcome.
Security should be a concern, whether it's an internal app or external. Most hacks now-a-days are done by social engineering their way into the intra-net of a company. Take the recent Target breach. I believe they used the AC repair service to gain access to the building. I went to a Schmoocon talk once where a guy hired to test a companies' security actually got a job as a janitor and would plug in a Linux device he built, go mop some floors, then pick up the device which had scanned all their internal networks. So, yes, if you believe you should guard against an attack, then I would say do so.
How do I handle simultaneous concurrent inputs for the same response and request?
Not sure what you mean by this. Spring MVC typically uses session to isolate requests. If two different users request the same thing, they are two different requests for the same thing. I would suggest using some caching so that you are not hitting your DB every time, but other than that I see no problem.

Why javax.ws.rs.Produces in Java REST style can take some MediaTypes

I don't understand why javax.ws.rs.Produces can take more than two Media types. As I know, web service client must know exactly what is media type return by the web service. I took a look at its API at http://docs.oracle.com/javaee/6/api/javax/ws/rs/Produces.html but I didn't find my answer. Anyone has any ideas? Thanks.
A restful endpoint can return any number of media types. This allows the service to support multiple clients that may have different requirements. The clients tell the service what content type they expect to be returned by setting the Accept header or in some cases using a special suffix on the url like .json or .xml.
Example:
Let's pretend you have two clients calling the same web service.
Client A may only be able to parse XML. So they request an XML
response by sending application/xml in the Accept header.
Client B may be able to parse both XML and JSON, but they prefer
JSON. So they send application/json in the Accept header.
In order for the restful endpoint to support both of these requests it would be annotated as follows:
#GET
#Produces({"application/json", "application/xml"})
public Foo getFoo()
{
return Foo(); //This will be marshalled to XML or JSON depending on what the client requests
}

What's an appropriate way of appending metadata to objects before returning via a RESTful WS?

I have a RESTful web service that responds to /user/{userId} with a marshalled XML representation of a User domain object (using JAXB). What's an appropriate way of communicating back to the client additional details about their request, particularly if it doesn't return the information they're expecting? In a non-distributed Java application, you might have a catch block that deals with data access, or security exceptions. In the event that /user/{userId} doesn't return anything (e.g. the web services persistence mechanism isn't working, there is a security restriction, etc...) how do I include meaningful information in the response to the client?
I don't think DTOs are what I need because I'm not looking for different representations of a domain object. Rather, I'm looking for information about what happened during the request that may have prevented it from returning the information the client expected. Would it be appropriate to enclose the domain object within some kind of ResponseObject that holds the relevant metadata? The downside to this approach is that I'd rather not have my service layer interfaces all have ResponseObject as their return type because I may very well provide a non-RESTful implementation that doesn't have the same metadata requirements.
What's an appropriate way of communicating back to the client additional details about their request, particularly if it doesn't return the information they're expecting.
In the event that /user/{userId} doesn't return anything (e.g. the web services persistence mechanism isn't working, there is a security restriction, etc...) how do I include meaningful information in the response to the client?
This is what the HTTP Status Code is used for in a RESTful service.
To indicate that a requested userId doesn't correspond to an actual user, you can return a 404 Not Found.
To indicate an internal error within your application (such as not being able to connect to the database), you can return 500 Internal Server Error.
The option you are describing - wrapping your returns in a ResponseObject which then includes the true "response status" - sounds an awful lot like SOAP.
The beauty of REST, or at least what people claim, is that you can use the already-existing HTTP response status code to model almost all statuses of your actual response.
If it's really error situation (security problems, no DB connection or even user with provided ID not found), then just throw an Exception. Client receives fault and can behave according to information contained in it.
Which implementation do you use? In Apache CXF, for example, you can define exception handler and render XML for exception yourself, and there you are free to include any meta-info you like.
I would capture the information using exceptions, then map those exceptions to an HTTP response with the appropriate status code. You can achieve this by creating an implementation of ExceptionMapper if you're using JAX-RS, or you can subclass StatusService if you're using Restlet.
http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features
http://wiki.restlet.org/docs_2.0/13-restlet/27-restlet/331-restlet/202-restlet.html

Java REST client without schema

Goal
Java client for Yahoo's HotJobs Resumé Search REST API.
Background
I'm used to writing web-service clients for SOAP APIs, where wsimport generates proxy stubs and you're off and running. But this is a REST API, which is new to me.
Details
REST API
No WADL
No formal XML schema (XSD or DTD files). There are example XML request/response pairs.
No example code provided
Progress
I looked at question Rest clients for Java?, but the automated solutions there assume you are providing both the server and the client, with JAXB invoked on POJOs to generate a schema and a REST API.
Using Jersey (a JAX-RS implementation), I have been able to make a manual HTTP request:
import com.sun.jersey.api.client.*;
...
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
WebResource webResource = client.resource("https://hj.yahooapis.com/v1/HJAuthTokens");
webResource.accept("application/xml");
// body is a hard-coded string, with replacements for the variable bits
String response = webResource.post(String.class, body);
// parse response into a org.w3c.dom.Document
// interface with Document via XPATH, or write my own POJO mappings
The response can look like:
<?xml version="1.0" encoding="utf-8"?>
<Response>
<ResponseCode>0</ResponseCode>
<ResponseMessage>Login successful</ResponseMessage>
<Token>NTlEMTdFNjk3Qjg4NUJBNDA3MkJFOTI3NzJEMTdDNDU7bG9jYWxob3N0LmVnbGJwLmNvcnAueWFob28uY29tO0pVNWpzRGRhN3VhSS4yQVRqRi4wWE5jTWl0RHVVYzQyX3luYWd1TjIxaGx6U0lhTXN3LS07NjY2MzM1OzIzNDY3NTsxMjA5MDE2OTE5OzZCM1RBMVNudHdLbl9VdFFKMFEydWctLQ==</Token>
</Response>
Or, it can look like:
<?xml version="1.0" encoding="utf-8"?>
<yahoo:error xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xml:lang="en-US">
<yahoo:description>description</yahoo:description>
<yahoo:detail>
<ErrorCode>errorCode</ErrorCode>
</yahoo:detail>
</yahoo:error>
Questions
Is there a way to auto-generate POJOs which can be marshalled/unmarshalled without a formal schema?
Should I attempt to generate those POJOs by hand, with JAXB annotations?
Is there some tool I should be leveraging so I don't have to do all this manually?
It's interesting that they provide an HTTP URL as the namespace URI for the schema, but don't actually save their schema there. That could be an oversight on their part, which an email or discussion-list posting could correct.
One approach is to create your own schema, but this seems like a lot of work for little return. Given how simple the messages are, I wonder if you even need a POJO to wrap them? Why not just have a handler that extracts the data you need using XPath?
Edit: blast from the past, but I saw the comment, reread the question, and realized that the first sentence was hard to understand. So, clarification:
One very good habit, if you're going to write a publicly accessible web service, is to make your schema document available at the same URL that you use for the schema's namespace URI -- or better, have that URL be a link to complete documentation (the W3C XSD namespace is itself a good example: http://www.w3.org/2001/XMLSchema).
I would suggest writing beans by hand, and only annotating with JAXB annotations if you have to. For most accessors/mutators (getters/setters) you do not have to; by default all public bean accessors and fields are considered, name is derived using bean convention, and default is to use elements instead of attributes (so attributes need to be annotated).
Alternatively you can of course write schema by hand, generate beans using JAXB, if you like W3C Schema a lot. And just use resulting code, not schema, for data binding.
As to POJO: that can be very simple. Something like:
#XmlRootElement("Response")
class Response {
public int responseCode;
public String responseMessage;
public String token; // or perhaps byte[] works for automated base64?
}
and similarly for other ones. Or, use getters/setters if you like them and don't mind bit more verbosity. These are just data containers, no need to get too fancy.
And if you must auto-detect type from content, consider using Stax parser to see what the root element, and then bind using JAXB Unmarshaller, handing XMLStreamReader that points to that root element. That way you can pass different object type to bind to.
And finally: sending/receiving requests: plain old HttpURLConnection works ok for GET and POST requests (construct using, say, URL.openConnection()). Jakarta HttpClient has more features if need be. So oftentimes you don't really need a separate REST client -- they may come in handy, but generally build on simple http client pieces.
I find HTTP4E very useful for making REST calls. It is an awesome Eclipse plugin, it has tabs, syntax coloring, auto suggest, code generation, REST HTTP call replay, etc.. It does a great job of HTTP debugging, HTTP tampering, hacking. I am having so much fun with it.
http://www.ywebb.com/
Try JdkRequest from jcabi-http (I'm a developer). This is how it works:
String body = new JdkRequest("http://www.google.com")
.header("User-Agent", "it's me")
.fetch()
.body()
Check this blog post for more details: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

Categories

Resources