obtain reference to JspContext/PageContext from a servlet - java

Does anyone know a way to get a JspContext reference from a servlet?
I have a servlet that forwards to a Jsp and I'd like to set some PageContext variables from within the servlet so they're ready for consumption in the Jsp.

Let me see if I understood: you want to invoke a JSP from a servlet and make some variables (which are under the control of the servlet) available to the JSP. Right?
Then forget about the PageContext, it's just specific to JSP pages and it can't be accessed from a servlet. Any attribute you set in the request, session or servlet context will be available in the JSP. The PageContext is a scope wider than the previous ones and it comes with a findAttribute method that, when invoked, will look for an attribute with given name inside the page's context, request, session or servlet context (in that order).
So, the only thing you need is to set those variables as attributes in one of those scopes, I would suggest to use the request one (HttpServletRequest.setAttribute("foo", "fooValue")) and then use it in your JSP using a value expression (${foo}).

You should use request scope.
A pageContext is obtained by a implementation dependent subclass of JspFactory in the service method of the JSP. In Tomcat, for example
public void _jspService(
...
pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
So pageContext doesn't exist before the request is sent to the JSP.

Related

How to send values from one jsp page to other but redirect to some other page?

I want to send values from jsp1.jsp to jsp2.jsp but redirect jsp1.jsp to jsp3.jsp . I used the following code in servlet for jsp1
response.sendRedirect("welcome1.jsp");
request.setAttribute("usern",user);
RequestDispatcher rd = request.getRequestDispatcher("afterlogin.jsp");
rd.forward(request,response);
but it keeps on giving this error "org.apache.jasper.JasperException: PWC6033: Error in Javac compilation for JSP".
you can use the possiblites of sessions in those case so you can access the parameter in jsp2 and redirect the jsp 1 to 3
https://www.javatpoint.com/servlet-http-session-login-and-logout-example
http://java.candidjava.com/tutorial/Servlet-Jsp-HttpSession-Login-logout-example.htm
You can use a HttpSession object as a user session, or use the ServletContext object for sharing global application information. Then use methods getAttribute (String attb) and setAttribute (String attb, String value) for sharing information within JSPs. The issue when you use a request is that the domain of the request is constraining you to use this information only when you receive this request.
You can also use JavaBeans to share information within JSPs
EDIT: Have you included your Java code inside a scriptlet? Using <% your code here %>
when you are using the sendRedirect function it will immediately redirect to that page it will not read next line code.
So according to your code your compiler is smart enough to check it so it is giving you an error.
please see below
1) SendRedirect ():
This method is declared in HttpServletResponse Interface.
Signature: void sendRedirect(String url)
1)In case of sendRedirect request is transfer to another resource to different domain or different server for further processing.
2)When you use SendRedirect container transfers the request to client or browser so URL given inside the sendRedirect method is visible as a new request to the client.
3)In case of SendRedirect call old request and response object is lost because it’s treated as new request by the browser.
4)SendRedirect is slower because one extra round trip is required because completely new request is created and old request object is lost.Two browser request required.
5)But in sendRedirect if we want to use we have to store the data in session or pass along with the URL.
2) Forward():
This method is declared in RequestDispatcher Interface.
Signature: forward(ServletRequest request, ServletResponse response)
1)When we use forward method request is transfer to other resource within the same server for further processing.
2)In case of forward Web container handle all process internally and client or browser is not involved.
3)When forward is called on requestdispather object we pass request and response object so our old request object is present on new resource which is going to process our request
4)Using forward () method is faster then send redirect.
5)When we redirect using forward and we want to use same data in new resource we can use request. setAttribute() as we have request object available.
more in : https://www.javatpoint.com/q/3577/difference-between-requestdispatcher-and-sendredirect

In java servlets, are ServletContext attributes available to views automatically?

If I set an attribute in my ServletContext object, does a view automatically have access to it? I'm trying to figure out how this JSP page is accessing a variable which is set in the ServletContextListener and nowhere else, so the only conclusion I can come up with is it must be available directly from the context object. If this is true, then what's the difference between setting a value in the ServletContext, and setting one in the request. Is it sort of like the difference between the session and the request?
Yes. You will have the access to it in JSP.
The Tomcat will convert/Generate servlets for all JSPs.
So you have almost same access what you have for Java Servlets in JSP too.
That means both of them will have access to servletConfig.
All jsp generated servlets will extend HttpJspBase which intern extends GenericServlet and GenericServlet has the ServletConfig property. Check this doc.
ServletContext attributes are attributes at the container[tomcat] level, as per the docs
/**
*
* Defines a set of methods that a servlet uses to communicate with its
* servlet container, for example, to get the MIME type of a file, dispatch
* requests, or write to a log file.
*
* <p>There is one context per "web application" per Java Virtual Machine. (A
* "web application" is a collection of servlets and content installed under a
* specific subset of the server's URL namespace such as <code>/catalog</code>
* and possibly installed via a <code>.war</code> file.)
*
So there will be only one context per application and what ever the attributes you set will be accessible to all servlets, irrespective of any particular session or request.
Where as Session attributes are attributes set at the session level, there can be many sessions going on in the container and it is maintained by both the client[usually browser] and the container using session-id mechanism. You will have the access to the attributes set in a session, till the session ends.
Finally Request attributes lifetime is till you serve that request. Once your container sends back the result, the attributes you set will be destroyed.
Check the below javaDoc of ServletRequest.removeAttribute(...)
/**
* Removes an attribute from this request. This method is not generally
* needed as attributes only persist as long as the request is being
* handled.
*/
public void removeAttribute(String name);

Can a jsf managed bean behave like a servlet?

Normally, a servlet has doGet() and doPost() methods. They are utilized to capture the incoming request parameters, which can then be used in any part of the application, if the developer wishes so.
Now, If instead of using a servlet, a developer wishes to use a jsf managed bean, is there a way to get the request parameters in the bean itself ? If so , how can it be done ?
I have seen this POST which shows a way of getting stuff from request in JSF. Can this be used to get a request parameter in managed bean like this :
HttpServletRequest origRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
String myReqQuery1 = origRequest.getParameter("ReqQuery1");
In this case, will the application follow a jsf life cycle or a servlet life cycle or both ?
JSF does not really work like that. The form fields in the view (.jsf or whatever) are mirrored by fields and properties in the bean. They are automatically populated by JSF when the servlet is invoked further up the stack.
This makes the need to read HTTP parameters redundant except when the browser lands on a JSF page from a non-JSF based form. For that something like Spring-MVC can accept the URI being targetted and make a connection to the ManagedBean instance before redirecting the browser to a JSF powered URL.

What is a "request scoped variable" in JSF

I was reading an article titled: "JSF 2 GETs Bookmarkable URLs".
The article has the following paragraph:
Introducing view parameters
The API documentation describes a view parameter, represented by the javax.faces.component.UIViewParameter component class, as a declarative binding between a request parameter and a model property. The binding to the model property is expressed using an EL value expression (e.g., #{blog.entryId}). If the expression is omitted, the request parameter is bound instead to a request-scoped variable with the same name.
Could someone kindly provide an example of a request scoped variable.
A "request scoped variable" is an variable which is stored as an attribute of the HttpServletRequest.
request.setAttribute("foo", foo);
This attribute is available in EL the usual way by #{foo}. The HttpServletRequest itself has a lifetime of exactly one HTTP request-response cycle. Once the HTTP response associated with the HTTP request has arrived fully at the client (the webbrowser), then the HttpServletRequest instance, including all of its attributes, is garbaged. JSF request scoped managed beans are by the way also stored as an attribute of the HttpServletRequest.
As JSF runs "on top" of the basic HTTP Servlet API, this is all easier to understand if you also understand how HTTP and the Servlet API work. This answer might give some enlightenment: How do servlets work? Instantiation, sessions, shared variables and multithreading.
Your subsequent question shall probably be "How is this related to the quoted paragraph then?" Well, it is basically telling that, when you omit the value attribute of the <f:viewParam>, that it instead is been put as a variable in the request scope.
So, if you use
<f:viewParam name="entryId" />
instead of
<f:viewParam name="entryId" value="#{blog.entryId}" />
then it becomes available as #{entryId} in the request scope.
<p>The entry ID view parameter is: #{entryId}</p>
This is however not the way view parameters are usually been used. You'd alternatively also just have used the #{param} map instead, hereby making the whole <f:viewParam> superfluous.
<p>The entry ID view parameter is: #{param.entryId}</p>
See also:
ViewParam vs #ManagedProperty(value = "#{param.id}")
A request scoped variable is instancinated for a each single request. So a request scoped variable instance does not exist in the context of another request.
A request scoped variable is, as the name implies, only valid in the current http request. A good use for request variables is when forwarding a request from a servlet to jsp. E.g set the variable in servlet, later read the same variable in jsp with ${myvar}
example(servlet)
request.setAttribute ("greeting", "world");
getServletConfig().getServletContext().getRequestDispatcher("/jsp/page.jsp").forward(request, response);
example(jsp)
Hello ${greeting}
id is mapped with entryId in Managed-bean config or u can use annotations.
<managed-bean>
<managed-bean-name>blog</managed-bean-name>
<managed-bean-class>com.acme.Blog</managed-bean-class>
<managed-property>
<property-name>entryId</property-name>
<value>#{param['id']}</value>
</managed-property>
</managed-bean>
#RequestScope: (this is the default scope of a managed bean). This puts the bean in request scope. It makes a new instance for every HTTP request. Commonly, the bean is instantiated twice, once when form is displayed and once when it is submitted.

ServletContext.getRequestDispatcher() vs ServletRequest.getRequestDispatcher()

why
getRequestDispatcher(String path) of
the ServletRequest interface cannot
extend outside the current servlet
context
where as
getRequestDispatcher(String path) of
the ServletContext can use the
getContext(String uripath) method to
obtain RequestDispatcher for resources
in foreign contexts.
and how??
Please help
If you use an absolute path such as ("/index.jsp"), there is no difference.
If you use relative path, you must use HttpServletRequest.getRequestDispatcher(). ServletContext.getRequestDispatcher() doesn't allow it.
For example, if you receive your request on http://example.com/myapp/subdir,
RequestDispatcher dispatcher =
request.getRequestDispatcher("index.jsp");
dispatcher.forward( request, response );
Will forward the request to the page http://example.com/myapp/subdir/index.jsp.
In any case, you can't forward request to a resource outside of the context.
The request method getRequestDispatcher() can be used for referring to local servlets within single webapp.
Servlet context based getRequestDispatcher() method can used of referring servlets from other web applications deployed on SAME server.
request.getRequestDispatcher(“url”) means the dispatch is relative to the current HTTP request.Means this is for chaining two servlets with in the same web application
Example
RequestDispatcher reqDispObj = request.getRequestDispatcher("/home.jsp");
getServletContext().getRequestDispatcher(“url”) means the dispatch is relative to the root of the ServletContext.Means this is for chaining two web applications with in the same server/two different servers
Example
RequestDispatcher reqDispObj = getServletContext().getRequestDispatcher("/ContextRoot/home.jsp");
I would think that your first question is simply a matter of scope. The ServletContext is a much more broad scoped object (the whole servlet context) than a ServletRequest, which is simply a single request. You might look to the Servlet specification itself for more detailed information.
As to how, I am sorry but I will have to leave that for others to answer at this time.
Context is stored at the application level scope where as request is stored at page level i.e to say
Web Container brings up the applications one by one and run them inside its JVM. It stores a singleton object in its jvm where it registers anyobject that is put inside it.This singleton is shared across all applications running inside it as it is stored inside the JVM of the container itself.
However for requests, the container creates a request object that is filled with data from request and is passed along from one thread to the other (each thread is a new request that is coming to the server), also request is passed to the threads of same application.
I think you will understand it through these examples below.
Source code structure:
/src/main/webapp/subdir/sample.jsp
/src/main/webapp/sample.jsp
Context is: TestApp So the entry point: http://yourhostname-and-port/TestApp
Forward to RELATIVE path:
Using servletRequest.getRequestDispatcher("sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> \subdir\sample.jsp
http://yourhostname-and-port/TestApp/fwdServlet ==> /sample.jsp
Using servletContext.getRequestDispatcher("sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> java.lang.IllegalArgumentException: Path sample.jsp does not start with a "/" character
http://yourhostname-and-port/TestApp/fwdServlet ==> java.lang.IllegalArgumentException: Path sample.jsp does not start with a "/" character
Forward to ABSOLUTE path:
Using servletRequest.getRequestDispatcher("/sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> /sample.jsp
http://yourhostname-and-port/TestApp/fwdServlet ==> /sample.jsp
Using servletContext.getRequestDispatcher("/sample.jsp"):
http://yourhostname-and-port/TestApp/subdir/fwdServlet ==> /sample.jsp
http://yourhostname-and-port/TestApp/fwdServlet ==> /sample.jsp

Categories

Resources