I have a java servlet with a URL Query string with instructions like this
http://hostname/servet?param1=value1¶m2=value2
I also structure the doPost/doGet like this
public void doPost(HttpServletRequest req, HttpServletResponse res) {
try {
doGet(req, res);
} catch (Exception e) {
e.printStackTrace();
}
}
public void doGet(HttpServletRequest req, HttpServletResponse res) {
try {
String sParam1 = req.getParameter("param1")
} catch (Exception e) {
e.printStackTrace();
}
}
I can access each queryString parameters via getParameter() for GET actions. But when I attempt to access the same queryString via getParameter() for POST actions, the returned value is NULL.
So, I would like to confirm this behaviour of getParameter for POST and GET actions. That is getParameter does NOT return queryString parameters for POST actions ? And do I need to manually dissect a query string to process them in cases of a POST action ?
For GET method, parameters are sent as part of the URL (the query string), for POST method parameters are sent as part of the body, that's why in the POST case you don't get the parameters, as they are searched in the body not in the URL.
do I need to manually dissect a query string to process them in cases of a POST action ?
Yes, if you are in the case where you are sending a query string but using method POST, you'll have to parse the query string by yourself, unless you honor the standards and send parameters inside the body rather than in the URL.
Related
I am trying to determine why a webserver response that initially throws an exception in processing; then returns a 200 OK client side. The details are as follows:
a request is sent to the webserver from the web application and if an error occurs an exception is caught and the relevant code &/or message is returned as follows:
public void dispatchRequest(HttpServletRequest req, HttpServletResponse
res)
{
if (method.equalsIgnoreCase("get")) {
doGet(req, res);
} else {
res.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
return;
}
}
void doGet(HttpServletRequest request, HttpServletResponse response)
throws
IOException,
HTTPServerException {
handleGetClient(request, response);
}
#SuppressWarnings("unchecked")
private void handleGetClient(HttpServletRequest request,
HttpServletResponse
response)
throws IOException, HTTPServerException {
...
} catch (IOException e) {
logger("I/O Error during playback with parameters (additional
parameters logged) {0}: {1}",traceParams,e.toString());
logger(Level.FINER, "I/O Error during playback with parameters {0}:
{1}", parameters, e.getMessage());
logger(Level.FINER, "I/O Error during playback with parameters {0}:
{1}", parameters, e);
sendError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
...
}
protected void sendError(HttpServletResponse response, int errCode) {
response.setContentType("text/plain");
try {
response.sendError(errCode,"ERROR");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
The handleGetClient method handles the process and in the event of an error throws exceptions which are caught. The method then uses the sendError method to set the error code returned and when log debugging I could see that this was set to in this specific error (500). But once the call returns to the dispatchRequest method the httpservletResponse status is actually (200). I cannot see where this happening and why. Initially I thought I could just change the method to int to return the error code but I am limited to the changes I can make on this code.
Any ideas?
You could try one of the following:
response.resetBuffer ();
response.setStatus (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.flushBuffer ();
or if you have an error page matching the 500 code in your web.xml:
response.reset ();
response.setError (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
You could also consider using an exception mapper, for any generic error, so instead of playing yourself with the error code, you could just throw an exception which would take care of the status code return.
i.e: throw new InternalServerException ("Your message");
Possibly a return statement might be in the catch block that eventually ends up in normal functioning of sending response. I am only stating a possibility. More you can do is check what is being returned after the request is processed successfully from server (either after exception handling or normal functioning).
Either your pasted code is missing a piece or the original code does not set the actual error on the response object. Somewhere is the sendError method there should be a line like:
response.setStatus(errCode);
Once you have started streaming response to the client, you can no longer change the response code, since it is returned in the first line of response and can never be changed afterwards. Same thing with response headers - once you've started streaming body content, you can't change them.
Now, servlet containers use buffering. This means that you can write some data to response and then change your mind (as #MehdiB. has indicated). But once you have overflown that buffer, the data is written to client (first status code, then headers, then body) and you can no longer change status at this point.
The probable solution here is to avoid writing body until you are sure there are no errors. If your body is long, but you can figure out its full lenght, you can add Content-Length header - in this case client will know if you don't deliver the response in whole without relying on status codes.
I remember in my practice adding servlet filters which will intercept HttpServletResponse to make sure that servlets behave nicely with regards to this constraint.
I can't retrieve the values from a request.
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String location_id = request.getReader().readLine(); // <---- null
location_id = request.getParameter("location_id"); // <--- null
PrintWriter out = response.getWriter();
out.write(this.get_events_json(location_id));
}
On the client-side:
$.get("EventServe", {location_id : location_id}).done(function() {
var events = JSON.parse(responseText);
outer_this.events = events.map(function(event){
var event = new Event(event.address, event.name, event.event_start, event.event_end)
return event;
});
outer_this.events.map(function(event){outer_this.insert_event(event)});
});
I've also tried to pass it in directly without jQuery, using only literals.
When you use $.get('EventServe', {location_id: location_id}, ...) to make a HTTP GET request, you are passing the value of location_id as a query string parameter to the specified URL. Essentially you are requesting: EventServe?location_id=4, where 4 would be the value of location_id.
On the server side, you can access the query string parameters via getParameter(String name):
public void doGet(...) {
String locationId = request.getParameter("location_id");
}
A few extra notes:
You should remove your call to request.getReader().readLine(). (Also, doesn't readLine(byte[] b, int off, int len) require arguments?)
As a followup to the previous point, manually reading from the request via a BufferedReader, InputStream, or anything similar is a bad (used loosely) habit to get into, as doing so may interfere with getParameter(String name) in some cases:
If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then reading the body directly via getInputStream() or getReader() can interfere with the execution of this method.
Source for the above quote.
Your client side code has a error where you define the function to run when the Ajax call is completed. The function should take events as an argument, as jQuery will automagically parse a JSON response:
.done(function (events) {
// Do things with the events
});
(Puts on pedant hat.) Your method name get_events_json does not follow Java conventions. Consider renaming it to getEventsJson or something to that effect.
Servlet Request Doc
Just look at getAttribute(String name) or getParameter(String name).
Edit: getParameter(String) is for POST request, but you perform a GET request. Use getAttribute(String) instead
I am using spring 3.2 and I have come with one requirement and can't figure out how to achieve it, first please look for below
We mostly use model in Spring MVC which is use for data binding
#ResponseBody annotation returns the string as http response
So my requirement is I want to use both together in single method base on condition, Here is my code
#RequestMapping(value="userAddEditSubmit.htm", method={RequestMethod.GET, RequestMethod.POST})
public String userAddEditSubmit(
#ModelAttribute("user") User user,
HttpServletRequest request, HttpServletResponse response, HttpSession session,
Model model
) throws Exception {
try {
//Here is my logic
return "redirect:" + url;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
So above is my method which returns specific jsp with model attribute, but now in one condition I have requirement to return String data instead of whole jsp in the same method, what can I do to achieve this? Any help will be highly appreciated.
You can simply return null from that method when your condition is met and write to the response yourself. Spring assumes that when a method returns null it has handled the response itself.
Oh hello there, fellow SO members,
I have a web service that returns XML data using a simple get request that goes like this :
http://my-service:8082/qc/getData?paramX=0169¶mY=2
the service returns raw xml in the page according to the parameters' values.
I am trying to retrieve this data from a GET request in GWT using RequestBuilder, Request, etc.
However, the response gives me empty text, a Status code of ZERO (which doesn't mean anything and isn't supposed to happen), and so on.
Here's the simplified code that doesn't work.
public class SimpleXML implements EntryPoint {
public void onModuleLoad() {
this.doGet("http://my-service:8082/qc/getData", "0169", "2");
}
public void doGet(String serviceURL, String paramX, String paramY) {
final String getUrl = serviceURL + "?paramX=" + paramX + "&idTarification=" + paramY;
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, getUrl);
try {
Request response = builder.sendRequest(null, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
response.getStatusCode(); // Gives me 0 (zero) :(
}
#Override
public void onError(Request request, Throwable exception) {
// ... doesn't matter for this example
}
});
} catch (RequestException e) {
// ... doesn't matter for this example
}
}
}
I don't get why this wouldn't work, since this is REALLY simple, I've seen tutorials and they all show me this way of doing things..
Thanks in advance
The reason is, that browsers do not allow cross-site requests with AJAX (see Same Origin Policy).
This means, that you can only call a service on the same server, same port (using the same protocol) as your HTML page. If you want to perform cross-site requests, you can use JSONP, as explained in http://code.google.com/webtoolkit/doc/latest/tutorial/Xsite.html.
The following JavaScript
new Ajax.Request('/orders/check_first_last/A15Z2W2',
{asynchronous:true, evalScripts:true,
parameters:{first:$('input_initial').value,
last:$('input_final').value,
order_quantity:$('input_quantity').value}});
triggers an Ajax call to the checkFirstLast method in the OrderController:
#Controller
#RequestMapping("/orders")
public OrderController {
#RequestMapping("/check_first_last/{code}")
#ResponseBody
public String checkFirstLast(#PathVariable String code,
#RequestParam int first,
#RequestParam int last,
#RequestParam("order_quantity") int orderQuantity) {
Integer newResult = new Integer(last - first);
return newResult.toString();
}
}
If I want to write the newResult String from the checkFirstLast method into the result_text HTML element on the page that sends the Ajax request, replacing the value set by the initialResult JSTL variable:
<h2 id="result_text"><c:out value="${initialResult}"/></h2>
what change would I need to make to the controller method above (checkFirstLast), now that I have already included the Jackson JSON library in my project?
the flow in ajax is:
send request with javascript to server
process request on server
sent response back to client
process response with javascript and update the page
The 4th step is missing in the code you provide.
It seems to me you are using the prototype javascript framework, is this correct?
If you look at the documentation for ajax requests and the ajax options you will see you can specify callback function when the requests was handled with success, or when a failure occured.
Change your javascript to:
new Ajax.Request(
'/orders/check_first_last/A15Z2W2',
{
asynchronous:true,
evalScripts:true,
parameters:
{
first:$('input_initial').value,
last:$('input_final').value,
order_quantity:$('input_quantity').value
},
onSuccess: function(transport)
{
$('result_text').update(transport.responseText);
}
}
);
and let me know what it gives.
This is an abstract controller that I wrote to handle Ajax. This actually is from the Struts example on DispatchAction.
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
AjaxResponse ajaxResponse = null;
String parameter = "command";
try {
String methodName = request.getParameter(parameter);
Method method = getMethod(methodName);
ajaxResponse = invokeMethod(request, response, method);
} catch (Exception e) {
// TODO Auto-generated catch block
logger.error(e.getLocalizedMessage());
ajaxResponse = toXmlException(e);
}
if (ajaxResponse != null) {
//Finally
response.setContentType(ajaxResponse.getContentType());
response.setHeader("Cache-Control", "no-cache");
OutputStream out = response.getOutputStream();
out.write(ajaxResponse.getResponseText().getBytes());
out.flush();
}
return null;
}
As you can see, A javascript is sent to the server, which is then dispatched by the DispatcherServlet to the controller. The controller then invokes the correct method call and returns a response through response.getOutputStream().write(....).
The controller then must return a null so that the DispatcherServlet does nothing in return.
In my case, AjaxResponse is an interface and the response can be either XmlAjaxResponse or JsonAjaxResponse.
The java client then handles the response returned from the server (in this case, controller).
You need to add in a response to your side. Hope this helps.