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.
Related
In Velocity template engine I could just use a model variable
$request
which is a instance of HttpServletRequest. How to get a http request object in Freemarker template engine? According to the freemarker documentation,
http://freemarker.org/docs/api/freemarker/ext/servlet/HttpRequestHashModel.html#getRequest--
there is a class HttpRequestHashModel and its method returns a instance of HttpServletRequest.
So the question is, how to access this object in spring boot? I found some information about using a
${Request}
variable, but I got an error that it returns a null/missing object.
As far as I know, Spring does not expose the request directly to the template, however by default it does expose the model attribute springMacroRequestContext, which contains a lot of information about the request.
The springMacroRequestContext variable allows you to fetch information about the request.
For instance:
<html lang="${springMacroRequestContext.locale.language}" class="no-js">
or
${springMacroRequestContext.contextPath}
With your requirement of getting the path:
${springMacroRequestContext.requestUri}
should probably be sufficient.
See the org.springframework.web.servlet.support.RequestContext for all the available methods.
You can change the name of this attribute by setting the following property in your application.properties:
spring.freemarker.request-context-attribute=rc
This allows you to shorten the syntax in your template:
${rc.locale}
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.
I have a viewscoped bean wich receives parameters through f:viewparam and set values in the model using them. After a page postback, the parameters dissapear from the url but the model values setted by the initial params are retained somehow.
Is this a safe way of keeping parameters or should I rewrite the url on postback so it keeps the initial parameters subsequent calls?
How are the parameter retained? In the viewstate?
Here's what the f:viewParam documentation says:
[...] this tag causes a UIViewParameter to be attached as metadata for the current view. Because UIViewParameter extends UIInput all of the attributes and nested child content for any UIInput tags are valid on this tag as well.
This means that the <f:viewParam> value attribute will be updated with the request parameter, stored in the viewstate and re-set/revalidated when you submit the page again.
Arjan Tijms has the full story here: http://arjan-tijms.omnifaces.org/2011/07/stateless-vs-stateful-jsf-view.html
In short: using a #ViewScoped bean is perfectly fine, but if you use an expensive validator/converter on that value be aware that it will be called again on each postback from that page. If you want to avoid that, have a look at this article from BalusC, which explains o:viewParam, OmniFaces' stateless alternative.
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.
How many values available for "scope" attribute in "action" element of
struts-config.xml file other than "request" and "session"?
<action name="loginform" path="/bkplogin" scope="?" type="org.springframework.web.struts.DelegatingActionProxy">
There are only two possible values for the scope attribute: request and session as stated in the struts-config’s DTD:
<!--
The name of a JSP bean scope within which such a form bean may be accessed.
-->
<!ENTITY % RequestScope "(request|session)">
...
...
<!ATTLIST action scope %RequestScope; #IMPLIED>
See the DTD here:
http://struts.apache.org/dtds/struts-config_1_3.dtd
or a more human readable documentation of the DTD here:
http://struts.apache.org/1.x/struts-core/dtddoc/struts-config_1_3.dtd#action
What about the "Application" and "page" ?
Well, the scope of an object across JSP pages can be:
page - an object can be accessed only from within the same JSP page it was created in;
request - objects created using the request scope can be accessed from any pages that serves that request;
session - an object is accessible from pages that belong to the same session (spans across multiple requests of the same client, with state maintained in the session, each client with his own session);
application - objects from this scope can be accessed from any pages in the application (all users share the same objects in application scope, one object to all users).
Now, the scope in struts-config refers to where to create/find ActionForm objects. An ActionForm represents the server object representation of a client HTML form.
It does not make any sense to have the form with application scope because it will be one form for everybody which which I can't even think at what that will be useful. So no application value for that field.
Now imagine you have page scope. How will that work? Struts does a RequestDispatcher.forward/redirect to go to the JSP files, how is it going to save the ActionForm in the page scope of the page that still does not have a page scope since it does not yet have control?! Is just like sending values to a method but instead of sending method arguments you are trying to directly create local variables in the code of the method from outside the method.
So there are only two values that make sense: request and session. If you want something extra you have to manage it yourself.
Struts is a generic framework, it does not cover every imaginable or unimaginable case, it covers most of normal use case scenarios for which request and session is all you will ever need.