Different "request" implicit objects in Liferay - java

What is the difference between fetching attributes from these implicit objects:
renderRequest.getAttribute("myVar")
actionRequest.getAttribute("myVar")
request.getAttribute("myVar")
Why are they all allowed?
I mean you usually store attribute in actionRequest or renderRequest object but you can get it in request implicit object, why?
What is the correct approach?
How is it possible to get an action object in view time?
Does not it violate the action-render renderParams passing mechanism?
Why are actionRequest/response available as implicit object if they throw NullPointerException when trying to use them in JSP?
Finally when is it useful to store an attribute in the request (PortalUtil.getOriginalServletRequest)?

What is the correct approach for accessing request attributes?
In portlets, the correct approach is to only interact with the renderRequest for retrieving parameter values and for getting or setting request attributes (in JSPs or the portlet class). renderResponse can be used to create new Portlet URLs.
Why can you get request attributes from the request object as well?
request is an HttpServletRequest and renderRequest is a PortletRequest. However, Liferay implemented request as a wrapper of HttpServletRequest in such way that, e.g. for accessing request attributes, it will fallback to the PortletRequest if it doesn't find the attribute in the actual HttpServletRequest.
What's the use of actionRequest and actionResponse at view time?
Like you say, if you follow the principles of MVC, you will only use the JSP for view logic. If you check the DefineObjectsTag from Liferay, you can see that all these xxxRequest and xxxResponse objects are only set if the portlet is in the right lifecycle. Because, normally, you're in the RENDER_PHASE when executing the JSP logic, only renderRequest and renderResponse will be not-null.
When is it useful to store an attribute in the request?
It doesn't really make sense to store attributes in the HttpServletRequest if you're working with portlets. On the other hand, inside a servlet (filter) you could add attributes that can then be retrieved from portlets by using request.getAttribute("xxx").

Related

How does Tomcat maintain same session object across multiple request? [duplicate]

This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 3 years ago.
I have read that everytime an HTTP request is made to tomcat for a servlet it creates a new HTTPRequest Object and using that request object we can access session object and store information. This session object stores the information across multiple requests.
I want to understand if tomcat is creating a new HTTPRequest object for every request coming from a browser, then how it is able to attach same session object across multiple requests?
Apache is a servlet container.
The servlet container is attached to a webserver which listens on HTTP requests on a certain port number, which is usually 80. When a client (user with a web-browser) sends a HTTP request, the servlet container will create new HttpServletRequest and HttpServletResponse objects and pass it through the methods of the already-created Filter and Servlet instances whose URL-pattern matches the request URL, all in the same thread.
The request object provides access to all information of the HTTP request, such as the request headers and the request body. The response object provides facility to control and send the HTTP response the way you want, such as setting headers and the body (usually with HTML content from a JSP file). When the HTTP response is committed and finished, then both the request and response objects will be trashed. Source : https://howtodoinjava.com/server/tomcat/a-birds-eye-view-on-how-web-servers-work/
First of all, it is important to note that a servlet container does not necessarily create a new instance of HttpServletRequest for each request.
Tomcat, for example, recycles existing instances of HttpServletRequest as a performance optimization to reduce heap allocation. After a response has been committed, it resets the internal state of the existing HttpServletRequest instance and reuses that same instance for the next request. Same thing for the HttpServletResponse instance.
As a consequence, since this object is not immutable it's critically important to make sure that a HttpServletRequest object is not referenced anywhere outside the lifecycle of a single request.
To answer the OP's question: the HttpSession object is not something that's stored in a field of HttpServletRequest. HttpServletRequest.getSession() is just an API method, and the servlet engine typically implements it by retrieving the HttpSession from the session storage mechanism using the session ID provided by the request.
NOTE: there is also no guarantee that that the same actual instance of HttpSession will be returned for subsequent requests connected to the same session (see this question)
Although the HttpRequest object is created for each request the HttpSession object is persisted between the requests. The session is identified by JSESSONID cookie or request parameter (in case cookies are disabled) as explained in this answer.
As per Servlet 3.0 Specification:
HttpSession objects must be scoped at the application (or servlet
context) level. The underlying mechanism, such as the cookie used to
establish the session, can be the same for different contexts, but the
object referenced, including the attributes in that object, must never
be shared between contexts by the container.

How to get parameters from the URL in Liferay

I have a portlet developed in Liferay, in which I want to get query parameter value from URL.
I tried this way but get "null" value from Query parameter:
HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(request);
HttpServletRequest httpOrigReq = PortalUtil.getOriginalServletRequest(httpReq);
String myValue = httpOrigReq.getParameter("idProcessOrigin");
Any advice would be greatly appreciated!
The code you mention in your question should work, however, it's ignoring the peculiarities of a portlet environment. Typically, in a portlet, you'd rather "decorate" the names of parameters with <portlet:namespace/> (or whatever the equivalent in your UI library of choice is to this JSP tag). Instead of submitting a parameter "idProcessOrigin", you'd submit "<portlet:namespace/>idProcessOrigin" (of course, with properly replaced namespace, e.g. rather SOME_RANDOM_STUFF_idProcessOrigin)
If you don't want this, you can also declare the property com.liferay.portlet.requires-namespaced-parameters=<boolean> in your portlet-#Component's property list (as carried over from liferay-portlet.xml)
For the standard way of obtaining the parameters from a portlet request, you don't need to go through the HttpServletRequest at all - just use the PortletRequest's getParameter method. The result of this method depends, however, on properly decorated parameter names (or the deactivated option mentioned above). Note: When you call request.getParameter("idProcessOrigin"), you don't need the decoration any more, provided that request is a PortletRequest, not an HttpServletRequest.

how can i get the PortletRequest

My problem is to obtain PortletRequest from HttpServletRequest
I put this sentence:
PortletRequest request = (PortletRequest) HttpServletRequest.getAttribute();
What should I put into the .getAttribute();
When I developed in IBM Portlet Factory, I used .getAttribute(Constants.PORTLET_REQUEST)
The Constants are into one .jar
Now I need to do this with Portlet in JSR168 or there is another way to obtain PortletRequest without using HttpServletRequest
I hope you can help me
You can use something like this:
(PortletRequest) request.getAttribute("javax.portlet.request");
(PortletResponse) request.getAttribute("javax.portlet.response");
Request and response are of HTTPServletRequest and HTTPSevletResponse.
I assume you're programming a servlet since you have a HttpServletRequest and no PortletRequest. Which means you won't have a PortletRequest. You'll need to be programming portlets to get PortletRequests and in that case, the API interfaces and portlet container provide the PortletRequest.
I don't know how the internals of Portlet Factory worked that you would need to obtain a PortletRequest like that but that's not typical portlet programming.
You say you are making a JSR 168 portlet.
In that case your portlet class should be implementing javax.portlet.Portlet
To implement that interface you implement:
render(RenderRequest, RenderResponse)
and
processAction(ActionRequest, ActionResponse)
These are called by the portlet container when it decides to render your portlet or handle a user action from your portlet.
The request objects RenderRequest and ActionRequest are PortletRequests. So you get it directly as an argument, you don't have to query something for it.

set content length from struts2

how can I set content length from struts2 action class? as I access my web app from mobile, mobile client browser is complaining that content length required. Only one mobile is giving me headache. Thanks.
If you want set it for specific Action-classes you can get an object of HttpServletResponse and can than set the content length like
HttpServletResponse response=ServletActionContext.getResponse();
response.setContentLength(lenght);
Other good way is to implement ServletResponseAware and let Struts2 inject response as a map in your action class (clean way).
Other good way is to do such work in an interceptor,create your custom interceptor and place it where you want to do some pre-processing and post-processing.
Other way is to create a Filter and place it before Struts2 dispatcher Filter and let your filter do any custom logic you want to have with request and response object.

How to get url request parameter from inside LIferay/IceFaces/JSF portlet backing bean

Is posible for a portlet to read a request parameter of its surrounding page?
E.g. the URL of the page the portlet resides in is http://example.com/mygroup/mypage?foo=bar Is it possible to read the "foo" parameter from a portlet that is on that page?
Portlet Container is Liferay 6.0.5.
P.S.
I have already tried:
com.liferay.portal.util.PortalUtil.getOriginalServletRequest(com.liferay.portal.util.PortalUtil.getHttpServletRequest((javax.portlet.PortletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest())).getParameter("foo")
but I always get null for productId
Thanks!
Have you tried
ExternalContext.getRequestParameterMap()
The following code will do the trick:
javax.portlet.PortletRequest pr = (javax.portlet.PortletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("javax.portlet.request");
java.lang.reflect.Method method = pr.getClass().getMethod("getOriginalHttpServletRequest");
HttpServletRequest httpServletRequest = (HttpServletRequest)method.invoke(pr, new Object[] {});
return httpServletRequest.getParameter(YOUR_PARAM_KEY);
In a partial submit, the icefaces ajax bridge (which replaces a usual jsf portlet bridge) is avoiding the normal portal action/render request, contacting directly the blocking servlet (in order to avoid invalidating other request-scoped portlets and in general, to be faster). Because of this, all those params/attributes which are set in a normal portal request are not set in ajax. They are set only in the initial GET type request for that page. So, actually what you should do is saving those params in the #PostConstruct or some other method of your controlling bean, and then reuse them later. (They wouldn't change in a partial submit anyway, right?).
Keep in mind though, that this will not work if you use IceFaces in conjuction with Spring (and their EL Resolver, since that eliminates your extended request scope).
if you are in JSF environment then try this:
String param = LiferayFacesContext.getInstance().getRequestQueryStringParameter("foo");

Categories