Why do I need an HttpSession to get the ServletContext? - java

In the Java Servlet API, the only way to get the ServletContext is through an instance of HttpSession (Javadoc).
What if I don't want to create a session and only need the servlet context? In other words, why is there no getServletContext() method in the HttpServletRequest class?
EDIT
I know I can get the ServletContext from the servlet itself, since it receives it during its initialization. However, I cannot get it from a HttpServletRequest alone, even though it's linked to a servlet. So what if I have a request, but no reference to any servlet?

getServletContext() is part of GenericServlet which is the parent class for HttpServlet so you should be able to call it in your servlet implementation.
Edit:
HttpServletRequest inherits getServletContext() from ServletRequest since servlet 3.0, so it looks like you will have to pass a context along with the request and response objects if you have to use a version prior to 3.0.

It's just that every entity working with requests (servers, filters, pages) has its own getServletContext (or init())

Your servlet class has a getServletContext() method you don't need to go to the request.
This makes sense, the servlet itself has a context provided by the container, this is independent of any particular request.

Related

HttpServletResponse with #Context annotation always null

I'm new to JAX-RS and I'm trying to understand how the #Context annotation works. I have a REST service and am currently using certain filters to do extra processing for different request types. Inside one of those filters is the following line:
public class SentryFilter {
#Context
HttpServletResponse response;
...
This value is used later on in the filter() method of that filter. The problem is that the response object is null. I've stepped through a debugger and can't determine why it's null.
From what I've read in the JAX-RS documentation, the #Context annotation for HttpServletResponse can be filled by the resource methods. So, I modified my the API I'm calling to include HttpServletResponse
public interface APIStuff {
#Path("deviceName")
#GET
#Sentry
String getDeviceName(#PathParam("deviceId") #Size(min = 1, max = 1024) final String deviceId, #Context HttpServletResponse httpServletResponse);
...
This returns the same HttpServletResponse is null error.
So the question is, where is this value supposed to be "filled"? The person who wrote the filter class obviously did so with the belief that the response object would be filled, so I don't think it's a matter of passing in #Context HttpServletResponse to the filter() method.
The #Context annotation allows you to inject request/response context details into JAX-RS provider and resource classes. Injection can be performed into a class field, a bean property or a method parameter.
The types available for injection are listed in this answer.
You haven't provided any details about how your application is deployed, but be aware that HttpServletResponse is available for injection only when the application is deployed in servlet containers (Tomcat, for example). It might be your problem.
#Context varies with usage and depends on what is actually being injected. If you are injecting the HttpServletResponse, it needs to be part of the method signature. This is because most beans are implemented as a singleton, and having multiple requests will just override the response if implemented at an instance level.
As an aside, IMO the API should support injecting the method-only '#Context' resources into a (for example) ThreadLocal<HttpServletResponse>
Your Filter that you posted does not extend javax.servlet.Filter, are you including the full signature? how is this filter being used?
As to why your resource method level injections are turning up null, are you sure it's actually being called within the servlet context?
As #cassiomolin said, you haven't provided any details about how your application is deployed, HttpServletResponse is available for injection only when the application is deployed in servlet containers (Tomcat, for example). It might be your problem.
I had similar problem with GrizzlyHttpServer.
Cause of my issue was, Grizzly provides similar abstractions to those offered by the Servlet specification: HttpHandler (Servlet), Request (HttpServletRequest), Response (HttpServletResponse).
So I had to use: import org.glassfish.grizzly.http.server.Request;
instead of: import javax.servlet.http.HttpServletRequest;

In jersey2.x how to inject HttpRequest and HttpSession object ? how to use injected object outside

Using Jersey 2.x how would I inject HttpRequest and HttpSession objects? And how to use injected request and Httpsession object in a service class?
in jersey 2.x injected request and session objects in Resource class working fine getting request and session objects
out side like business class not working.
You can try adding #Context HttpServletRequest request to your resources method signature. That will make request available for the duration of the method.
It's not good practice to pass HttpServeltRequest / Session objects down to service or business classes. If you do this, you make it very difficult to use the service class in anything but a Web Application. You should pull the data that the service class requires out of the HttpServletRequest / Session in the Resource class and pass it to service class
For example, if your service class needs access to the userName that is held in an HttpServletRequests "userName" parameter, then the Resource class should do
String userName = req.getParameter("UserName");
serviceClass.doSomething(userName);
rather than
serviceClass.doSomething(req);

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.

Different "request" implicit objects in Liferay

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").

How to get ServletConfig object in Filter

Is there any way to get ServletConfig object of the servlet in a Filter applied to that servlet?
Edit-> The scenerio is i have mentioned the names of roles(who can access the servlet)
in the 'init-param' of the serlvet declaration in web.xml
The applied filter will check(using ServletConfig) whether the person who is trying to access the servlet is authorized(in roles) to access it or not.
You can't. ServletConfig is tied to a specific servlet, just like FilterConfig is for filters.
Which servlet config you want to access inside a filter? Note that a filter does not necessarily need to delegate to an underlying servlet directly. It can pass request to another servlet, choose servlet based on some condition or even handle the request completely without touching any servlet.
That being said these two abstractions are not accessible within each other.

Categories