In my web application , I get a request from the client. I process the request in my jsp page or the servlet(which ever is called) and want to forward to other jsp's or servlets accordingly. But before forwarding I want to set a few parameters and then forward it with these new parameters. The old parameters should not be present when forwarding. Only the new parameters should be present. How can this be done?
Can I forward from a servlet to jsp and vice-versa?
Please tell how the above can be accomplished?
If you have no use for the request parameters and your jsp/servlet has not written anything to the response, then I suppose it would be fine to use redirect instead of forward, since redirecting will discard the request along with the parameters.
When you do redirect, you can create dynamically and set the querystring like so:
response.sendRedirect("url?a=" + var1 +"&b=" + var2);
Take note that this will be a GET method to the url. If url will be resolved to a servlet, you can implement the doGet method to just call the doPost.
Please note that a redirect will be ignored if the jsp/servlet has written something already on the response...
You can use request dispatcher and redirect as per your need and requirement.
ServletContext sc = getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher("url");
rd.forward(request,response);
or
response.sendRedirect("url");
sendRedirect() sends the header back to the browser , which contains the name of the resource to be redirected to. So this will be a new request to the resource from the browser .
forward() action takes place within the server without the knowledge of the browser .
yes you can forward the parameter servlet to jsp and jsp to servlet.
when you can set the attribute in request then it will lost on destination.means you can not access that on third resource.
request.setAttribute(attribute name,attribute value)
you can do same thing in session also.
You have to forward to JSP/Servlet using RequestDisptcher. Set the request attribute on the request to set parameters using
request.setAttribute(name, value)
The Forwarded JSP can read the parameter using
request.getAttribute(name)
But, You cannot hide the attribute existing before forward by default. You can achieve this using Request Wrapper. Wrap the request before forwarding override the set and get attribute methods.
Below code explains
RequestDisptcher dispatcher = req.getRequestDispatcher("url");
HideExistingRequestWrapper requestWrapper =
new HideExistingRequestWrapper(request);
requestWrapper.setAtribute("forwarded", "forwarded value");
dispatcher.forward(requestWrapper, response);
Here is the code of wrapper implementation:
class HideExistingRequestWrapper extends HttpServletRequestWrapper {
private Map localattributes = new HashMap();
public HideExistingRequestWrapper (HttpServletRequest orignialRequest) {
super(orignialRequest);
}
public Object getAttribute(java.lang.String name) {
return localattributes.get(name);
}
public Object setAttribute(java.lang.String name, java.lang.String value) {
return localattributes.put(name, value);
}
}
use
ServletRequest.removeAttribute(name of your old attribute)
ServletRequest.setAttribute(name , value)
After setting the attributes, get the RequestDispatcher using
getRequestDispatcher(url)
and then use forward() method
Related
I'm working on a legacy code (Spring 2.5.x, Java 1.5), where controller passes Http Servlet Request to view like this:
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map attributes = new HashMap();
attributes.put("httpRequest", request);
return new ModelAndView("/path/to/page.jsp", attributes);
}
However what happens is that httpRequest attribute does indeed exist in the JSP Page context, but it contains current request (JSP page) and not the original (controller). The passed request is being used to extract some information from the URL. It appears that I can get around that problem by using a bunch of "javax.servlet.forward.*" attributes. This however puzzles me as it is pretty simple thing and I'd be happy to get it to work anyways or at least know exactly why it doesn't work now. Anybody has any ideas?
To begin with, it is a bad idea to store the request as attribute of request. If you need specific data for the current request, you can retrieve it directly using ${requestContext}, if you need to access to the URL, use ${requestContext.requestURL}. If you need to access to parts of this URL to display it in client side, it would be better to parse the url in server side (controller) by first obtaining it using StringBuffer url = request.getRequestURL(); and then setting the required data as attributes.
I am trying to print the browser URL using Java. I have come across codes where they have used "request.getRequestURI();" to retrieve the URL. What is this "request" in "request.getRequestURI();" ? How do we define it? Can i get an example of a code with "request" defined?
It is an HttpServletRequest object.
See: http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html.
Normally it is passed in to a method on your controller.
The request object retrieves the values that the client browser passed to the server during an HTTP request such as headers, cookies or parameters associated with the request. Among the most common use of the request object is to obtain parameter or query string values. The following demo illustrates how to use the request object for parsing form data. - See more at: http://www.gulland.com/courses/jsp/objects#sthash.zigrGeiE.dpuf
The request object is an instance of HttpServletRequest. The request object is implicitly defined in jsp pages. It is also a parameter in the doGet and doPost method of an HttpServlet
So in a servlet, you'll have something like:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
and in a jsp page, you can access an object, lets say the firstName string, attached to the request with expression language:
<p>${request.firstName}</p>
I have a filter that implements a custom convention for loading servlets and JSPs. In that convention I am using the following code to include the servlet:
servletContext
.getRequestDispatcher( uriDispatcherLocator.getServletLocation( uri ) )
.include( request, response );
and the following code to include the JSP (in the same filter):
servletContext
.getRequestDispatcher( "/index.jsp" )
.include( request, response );
Everything works fine, the servlet executes, then it includes the JSP and some irrelevant custom rules take place.
As you can see, at the very moment I include a servlet with request dispatcher I cannot send an http header response to the client.
The problem is that I want the servlet to have full control of the response as if it was called from inside the filter (because the filter will do nothing else than dinamically mapping the servlets according to their respective Class/JSP location in the project file system).
I can use .forward() instead of .include(), but if I do I will not be able to include a JSP after the servlet has been executed.
So, how would I allow the servlet to execute the code below when being included through a filter via RequestDispatcher interface?
response.sendRedirect( "/somePath" );
No Javascript hacks, I am willing to send the proper HTTP response from the server to make the browser behave correctly.
--
EDIT:
In other words:
I want to change the headers sent to the client from INSIDE an included servlet by using RequestDispatcher, but the docs states:
The included servlet cannot change the response status code or set headers; any attempt to make a change is ignored.
Your Filter includes your servlet
servletContext
.getRequestDispatcher( uriDispatcherLocator.getServletLocation( uri ) )
.include( request, response );
Your Servlet indicates it wants to redirect
request.setAttribute ("sendRedirect", "/some/path");
or, wishes to add one or more response headers
Map<String, String> respHeaders = new HashMap<String, String>();
respHeaders.put("Expires", "0");
respHeaders.put("Cache-Control", "no-cache");
request.setAttribute("respHeaders", respHeaders);
Your Filter checks for these special requests
Map<String, String> respHeaders =
(Map<String, String>) request.getAttribute("respHeaders");
for (String key : respHeaders.keySet()) {
response.setHeader(key, respHeaders.get(key)); // set response headers
}
String sendRedirect;
if ((sendRedirect = (String) request.getAttribute("sendRedirect")) != null) {
response.sendRedirect(sendRedirect); // redirect the client
}
EDIT: Perhaps some of your servlets are already driving the flow and setting response headers when called from outside an include. But, there's no way to reuse them as is. You can't simply include them and expect the same behaviour because the goal of a RequestDispatcher#include() is to provide for server-side includes (SSI) only.
Hence, we do not find any overloaded methods (or any setters that could modify this behaviour) in the API. If you want to include such servlets and retain their behaviour (like redirects) you would have to pass them a hint that they're running under an include context and so should submit their response requests.
request.setAttribute ("includeContext", true);
I want to use a normal spring mvc controler and request mapping using path variables.
I do not want to forward or redirect, just change the string that user sees.
#RequestMapping(value = "/Foo/{id}/*", method = RequestMethod.GET)
public ModelAndView getFoo(#PathVariable final String friendlyUrl) {
//how can I rewite the url that user sees ?
}
(the same behaviour as when you change the title of an existing question on stackoverflow)
If you watch the traffic in wireshark, firebug or something you see, that stackoverflow sends a HTTP 301 Moved Permanently to the final URL.
You could do the same.
For this you need the HttpServletResponse, you can add it to the method signature to get it injected.
Set the permanent redirect:
String rightUrl = urlCompleter.complete(friendlyUrl);
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Location", rightUrl);
Where you need to implement urlCompleter on your own, eg. look in the database table of entries and locate the right url component.
I have a HashMap of custom objects being passed to a JSP using RequestDispatcher and I am able to access the object and its properties using JSTL.
However the code fails in case the parameter is sent using response.sendRedirect() .
I am not sure what the reason is and how to make it work?
The response.sendRedirect() basically instructs the client (the webbrowser) to send a new request on the given URL. You'll also see this being reflected by a change in the browser address bar.
A new request does of course not contain the attribtues of the previous (or any other) request. That would otherwise have broken the whole concept of "request scope".
To preprocess a GET request, you need to do the job in doGet() method of a servlet and then redirect to the URL of that servlet instead.
E.g.
response.sendRedirect(request.getContextPath() + "/foo");
and
#WebServlet("/foo")
public class FooServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, Foo> foos = fooService.map();
request.setAttribute("foos", foos);
request.getRequestDispatcher("/WEB-INF/foo.jsp").forward(request, response);
}
}
Note that this problem is in no way related to having a hashmap of custom objects in the request scope.
See also:
Our servlets wiki page
You can not share a request attribute in response.sendRedirect as it creates a new request.
But, if you want that HashMap, in response.sendRedirect, you can put that in session like
request.getSession().setAttribute("myMap", [HashMap object]);
and can share between the servlet and JSP. This works in both RequestDispatcher and sendRedirect.