I am having an issue with an Ajax post to a RESTful web service in Java. The project utilizes a single servlet mvc model, with the Ajax post data being sent as JSON to the web service. The specific issue that is occuring is that I a unable to pull the data out of a HttpServletRequest object on the web service side. The POST goes directly to the web service, and I attempted to pull the data out with the following:
#Path(Ajax)
public AjaxResource(){
#Context
HttpServletRequest request;
#POST
#Produces("application/json")
#Consumes("application/json")
public Response postMethod(){
BufferedReader reader = request.getReader();
// additional code
}
}
I receive an IllegalStateException on the getReader() call on the request; from what I understand the input stream/reader can only be called once. I am unsure if this is due to the doPost method in the servlet doing a request.getParameter call as it seems to ago I'd hitting the servlet before this web service. Is there any other way to retrieve this data other than implementing HttpServletRequestWrapper in the servlet?
You should use #Context HttpServletRequest request as an argument of the resource method.
So it should be something like this:
public Response postMethod(#Context HttpServletRequest request){
// rest of the code
}
Related
I have designed a REST based post Service using Spring 3.
The service method consumes parameter as String and responds data as String. The param and response can be json or string
#RequestMapping(value = "/service", method = RequestMethod.POST)
public #ResponseBody String Service(#RequestParam("param") String param) {
Sample POST Request:
http://IP:PORT/test-project/service
param={"name":"John"}
Sample response to above request:
{"age":"31"}
Is there a way to safeguard this request against Cross Site Scripting?
If yes then how can I achieve XSS support once I receive request on param parameter??
If you aren't returning the parameter value (or any manipulation of it) in the response, you don't have an XSS vulnerability.
Not that it means that your service is completely secure, of course.
I am trying to make an API with Jetty Server, and I have this simple GET request:
#GET
public String helloWorld(){
return "Hello world";
}
In order to make a POST request, I assume that one must save the input to the Jetty server. I have tried to research for quite a while, but found nothing.
I imagine something like this:
#POST
public void Save(String stringToSave) {
// Save to DB?
}
You could likely google this but let me give you a quick overview. A Servlet is a chunk of code that is normally run during an HTTP action - GET, POST, etc. It is the original technology of the JavaEE world, having been released in the late 1990's.
A simple Java servlet, using modern annotations, would look something like:
#WebServlet(name = "SampleServlet", urlPatterns = "/sampleServlet")
public class SampleServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP POST is sent
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// called when an HTTP GET is sent
}
}
The important parts to note are that the class extends HttpServlet and that you have to write code to pull data out of the request and push it into the response. This isn't bad to do but it does have to be done.
JAX-RS is a newer standard, aimed simplifying the creation of REST services. It too is a chunk of code that runs during an HTTP interaction.
A simple example of this would be:
#Path("/sampleService")
public class SampleService{
#Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#POST
#Path("/v1/hello")
public Response sayHello( SomeObject someobject ) {
The code here is both simpler and a bit more complex. The use of annotations helps determine the path that the service exists on a URL (in this case /sampleService/v1/hello), the HTTP method, and the Content-Type for both the request and response. Additionally, if the SomeObject object is defined correctly, the JAX-RS framework will automatically deserialize the incoming JSON or XML payload into an object for you.
The Response object contains the HTTP response code (perhaps a teapot) and a response body. In this example, the body will be automatically serialized back to the requestor in a way that matches the Accept header of the HTTP request (i.e., JSON for an application/json Accept header and XML for application/xml).
Note that while not directly related the JAX-RS framework takes advantage of the Servlet framework. Indeed in JAX-RS you can access the HttpServletRequest and HttpServletResponse object in your methods.
Which way is "better"? In general I would recommend using JAX-RS where possible as it is the newer standard and is a bit easier to implement. However, if you do any work in the JavaEE world you're very likely to run into Servlet code so it's important to understand it too.
Note that both Servlets and JAX-RS require an application server of some sort. Jetty is one of those. Another very common one is Tomcat. The application server sets up the environment for your code and listens for incoming HTTP messages. When it gets one it looks to see if it knows how to handle the URL and routes to the appropriate place. In the servlet world the server routes solely on the URL. In the JAX-RS world the server routes on the URL and, if specified by the #Consumes annotation, the HTTP Content-Type header too.
There is much more but let's start there and see if it answers what you're after.
I'm trying to build an api with Google Cloud Endpoints.
As Cloud Endpoints does not provide authentication beside Googles own OAuth I try to build my own. Therefore I want to access the parameters provided for the API (for example #Named("token") token) inside a servlet filter.
Unfortunately I cannot find any of the provided information inside the httpRequest. Is that normal? Is there a possibility to access the parameters?
I would appreciate if someone could help me!
UPDATE:
With the infos from jirungaray I tried to build an authentication using headers but ran into the same problem. Used a REST-Client to send some headers as I could not figure out how to do this with the API Explorer. Inside my filter I try to access the token from the headers:
#Override
public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String authToken = httpRequest.getHeader(Constants.AUTH_TOKEN);
...
chain.doFilter(request, response);
}
The reason why I try to do something like this, is that I'm using Guice for Dependency Injection and want my token to be injected inside another object.
With Guice I have the following Provider using the token to inject a FacebookClient (using the token) per request.
#Provides
public FacebookClient getFacebookClientProvider(#Named("fbToken") Provider<String> fbToken) {
return new DefaultFacebookClient(fbToken.get(), Version.VERSION_2_2);
}
As described in the Guice wiki (SevletModule) this uses a sevlet filter to get the information from the request.
Is there any solution to achieve this kind of DI with Cloud Endpoints?
Philip,
Yes, it does makes sense you are getting an empty request. Your endpoint calls are first handled by Google (they receive the API calls) and then those are processed and sent to a handler in your app. As this is all done in the background it's very easy to miss that your endpoints aren't actually getting the same request you sent, they get a completely different request sent from Google's infrastructure.
Even though your approach should work including tokens info in url makes them easier to sniff, even if you use SSL or encrypt your params the token is there in plain sight.
For what you are trying to achieve I recommend you include the token as a header in your request and retrieve that header by accessing the HTTPRequest directly on the endpoint, this is injected automatically if you include an HTTPServletRequest param in you endpoint method.
eg.
public APIResponse doSomething(SomeComplexRquestModel request,
HttpServletRequest rawRequest) {
}
If you still feel you should go with your original approach just comment and I'll help you debug the issue.
I have an jax-rs endpoint as below. I need to post a message to a web page through this endpoint. When I execute the endpoint using a client the method with #GET executes. But the method with #POST does not execute. I need to know when will be the #POST method will execute. What should I do to invoke the #POST method.
#GET
#Path("/")
#Produces("text/plain")
public boolean getLoginStatus(#Context HttpServletRequest request) throws URISyntaxException {
return true;
}
#POST
#Path("/")
public boolean helloPost() {
return true;
}
You need to invoke a HTTP POST request from your client - be it a programmatic one (e.g. JAX-RS 2.0 client API), a browser or tools like curl etc. I would strongly suggest using Postman client as a chrome browser extension to execute a POST request and test out your REST service
Im new to java based web service development.
I need to create a web service which accepts multipart data(ex: zip file).
Please help me out how to mention that in the function.
below is my current web service code which is accepting data in the form of json.
#RequestMapping(value="/workitems/updateData", method=RequestMethod.POST)
#ResponseBody
public Object updateData(#RequestHeader String deviceToken, #RequestBody FormFields[]
formFields,HttpServletResponse response) throws Exception {
//some code
}
please guide me to how to accept the multipart data in the web service method.
thanks in advance.
#RequestMapping(
value ="/workitems/updateData",method=RequestMethod.POST ,headers="Accept=application/xml, application/json")
public #ResponseBody
Object updateData(HttpServletResponse response,#RequestHeader String deviceToken,
#RequestParam ("file") MultipartFile file) throws Exception {
}
You can support it as above.
You can use normal Upload technique which you use in Servlet - commons-fileupload.jar way.
The same code placed in a method inside your controller will work fine. Make sure you pass HttpServletRequest object to your method.