From the Java EE tutorial:
If the resource is static, the include method enables programmatic server-side includes.
If the resource is a web component, the effect of the method is to send the request to the included web component, execute the web component, and then include the result of the execution in the response from the containing servlet.
I'm not quite sure what they mean by "programmatic server-side includes" and how those differ from the web component case.
I mean, regardless of the resource I include, I pass a request/response object tuple to it and get some side-effects that I may or may not communicate to the client, right?
Could somebody please elaborate on this?
You've omitted the heading and text preceding your quotation. These provide important context for the comments you're asking about:
Including Other Resources in the Response
It is often useful to include another web resource, such as banner
content or copyright information, in the response returned from a web
component. To include another resource, invoke the include method of a
RequestDispatcher object:
include(request, response);
Thus, when the comments continue with
If the resource is static, the include method enables programmatic server-side includes.
they are characterizing the effect of the preceding code snippet, not introducing some new concept. A "programmatic server-side include" in this context is invoking the include() method of a RequestDispatcher() associated with a static resource. It has the effect of including the resource associated with the dispatcher, inline in the response being prepared. As such, this is "server-side" because it is all done by the server, transparently to the client, as opposed to the client having to make a separate request for the included resource.*
The distinction between the static and web component cases is about the resource associated with the RequestDispatcher on which that include() method is invoked -- i.e. what resource is to be included -- not about the component whose code contains the method invocation. A static resource is exactly a resource that can be identified by a URL that is not associated with a web component. Normally this means it corresponds to a file. The file content could be anything, but a common use is for it to comprise an HTML fragment, such as a header or footer shared by many web pages.
I mean, regardless of the resource I include, I pass a
request/response object tuple to it and get some side-effects that I
may or may not communicate to the client, right?
It's more accurate to view it as passing a request and response object to the RequestDispatcher. In the event that the dispatcher is associated with a static resource, no, the request and response objects are not presented to that resource (itself) because it has no mechanism for receiving or manipulating them. Instead, the servlet engine in which the code runs manipulates the response object as it decides is appropriate.
In the event that the target resource is a web component, yes, it will be able to read data from the provided request, manipulate the request and its context, and manipulate the provided response, all at its discretion. Generally, it cannot distinguish this case from the one in which it is accessed directly. But no, the component invoking include() has at best limited control over what is communicated to the client via that mechanism.
*For more information on the history of and inspiration for the "server-side includes" part of the term, consult Wikipedia.
Related
Is there a way to let my #ExceptionHandler methods have access to the model attributes populated by the #RequestMapping method that triggered the exception in question?
Or, more specifically for my problem: my models passed to my views have some data populated from #ModelAttribute (such as detailed information on the user account) methods, and I'd like those to be also set in my #ExceptionHandler methods.
For instance, since my error view page uses the same header and menu as my other pages, I want to show the current user name (and other info, such as number of unread messages etc).
I know the #ExceptionHandler exists outside the #Transaction (as it should!), so I obviously can't just (and don't want to) run some queries again. Rather, I'd like to pre-populate the ModelMap or ModelAndView or whatever, and make sure the exception handler gets hold of that - or at least that the model data is made available when rendering the view.
I hope this question makes sense, I'm fairly new to Spring MVC so I may be mixing a few concepts here and there...
The javadoc of ExceptionHandler states the following with regard to the arguments that can be passed to the handler method:
Handler methods which are annotated with this annotation are allowed
to have very flexible signatures. They may have arguments of the
following types, in arbitrary order:
1. An exception argument: declared as a general Exception or as a more specific exception. This also serves as a mapping hint if the annotation itself does not narrow the exception types through its value().
2. Request and/or response objects (Servlet API or Portlet API). You may choose any specific request/response type, e.g. ServletRequest / HttpServletRequest or PortletRequest / ActionRequest / RenderRequest. Note that in the Portlet case, an explicitly declared action/render argument is also used for mapping specific request types onto a handler method (in case of no other information given that differentiates between action and render requests).
3. Session object (Servlet API or Portlet API): either HttpSession or PortletSession. An argument of this type will enforce the presence of a corresponding session. As a consequence, such an argument will never be null. Note that session access may not be thread-safe, in particular in a Servlet environment: Consider switching the "synchronizeOnSession" flag to "true" if multiple requests are allowed to access a session concurrently.
4. WebRequest or NativeWebRequest. Allows for generic request parameter access as well as request/session attribute access, without ties to the native Servlet/Portlet API.
5. Locale for the current request locale (determined by the most specific locale resolver available, i.e. the configured LocaleResolver in a Servlet environment and the portal locale in a Portlet environment).
6. InputStream / Reader for access to the request's content. This will be the raw InputStream/Reader as exposed by the Servlet/Portlet API.
7. OutputStream / Writer for generating the response's content. This will be the raw OutputStream/Writer as exposed by the Servlet/Portlet API.
8. Model as an alternative to returning a model map from the handler method. Note that the provided model is not pre-populated with regular model attributes and therefore always empty, as a convenience for preparing the model for an exception-specific view.
So in order to populate the model of the view you will be using to display the error, you'll probably have to go with WebRequest
Thought its possible, but:
http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
Important Note: the Model may not be a parameter of any
#ExceptionHandler method. Instead, setup a model inside the method
using a ModelAndView as shown by handleError() above.
Seems you have to cant pass ModelAndView as in any other controller, so it has to be built once again + fetch possible values from HttpServletRequest.
I've been messing around with servlets and JSPs and I am a bit confused at something:
I've made a servlet (controller) which would dispatch the request to a JSP
I've set some attributes to the request object using setAttribute() method in my
servlet.
I can access the request object's parameters and attributes within the JSP without any
problem.
Now I've stored the request object as an attribute in the session object using
session.setAttribute("test", request).
I've written a second JSP (navigating to it from the first JSP would be through
Javascript when I click a particular button- by using the window.location function and
giving the address of the second JSP as the value)
In the second JSP, when I retrieve the request object from the session object, I get a
null value from all the attributes of the retrieved request object.
I can access the parameters of the retrieved request object BUT only if I had retrieved
the parameters atleast once in my first JSP using request.getParameter() method
otherwise they return null in my second JSP.
I am really new to this stuff and am confused about this behaviour. Why were my request object's attributes being 'erased' while the parameters remain intact (as long I had accessed the parameters in my first JSP; which is even more bewildering to me as it does not make sense IMO)
Any explanation would be appreciated! Thanking you in advance.
This is just an educated guess, but I think the problem is that request objects in your container of choice might be lazy about its parameters: when you ask it for a parameter it reaches out to some external context and pulls the required data, at the same time caching it.
Nevertheless, the reason of the strange behavior is not really important. The problem should be solved by not saving requests in session. A request object is only your handle to the current request, not a data store by itself. It might be using any mechanism underneath, for all we know the attributes may be stored in threadlocals. There is absolutely no contract that would make a request act as an archive of any sort. For example: what would it mean if I asked such a stored request for the security principal? Would I mean "the current principal of the session"? Would I mean "the principal as of the moment when the request was created"?
EDIT:
Out of pure curiosity I just took a peek at Tomcat's implementation (I have no idea which container you are using) and found that it supports my claims: not only most of the data is gathered lazily, but the request object is recycled! So if you try store it in a session and then use, you might find that you are using someone's else request.
There are 4 scopes in Java EE 5. In both Java EE 6 and Java EE 7 there are 5 scopes. The most used are:
Request scope
Session scope
Application scope (Web Context)
You can store some data in all the above scopes by setting the appropriate attribute.
Here is a quote from the Java EE API docs related to ServletRequest.setAttribute(String, Object) method in regard to request scope:
void setAttribute(java.lang.String name,
java.lang.Object o)
Stores an attribute in this request. Attributes are reset between
requests. This method is most often used in conjunction with
RequestDispatcher.
...
So with every new request the previous attributes you have set in request will be lost. After you have set an attribute in a request, you must forward the request to the desired page. If you redirect, this will be a totally NEW request, thus the attributes previously set will be lost. (If you still want use redirection read this: Servlet Redirection to same page with error message)
Those attributes that are set in a HttpSession (in the session scope) will live as long as the session lives and, of course, will be available to only the user to which session belongs.
As for the context attributes they are meant to be available to the whole web application (application scope) and for ALL users, plus they live as long as the web application lives.
As a conclusion, if you have previously set an attribute in the session it will be available to the same user as long as the session is alive.
Hope this will help you.
P.S.
Maybe this article will also be useful for you: How Java EE 6 Scopes Affect User Interactions
The only thing that this article uses Annotations for scoping, but you'll get the idea.
I really like functional programming, I like its immutability concepts and also it's no side-effects concepts for functions.
I'm trying to take some of these concepts into java.
Now I have some kind of a servlet which receives a request and if browser did not send a cookie to server then i would like to create a cookie with a certain path to the user.
now inside the servlet i don't want to hold that logic because its common to multiple servlets.
so i extract it into some kind of a cookie manager which will do that:
CookieManager.java.handleCookies(request, response)
Check if browser sent cookie.
If not set cookie with new session cookie value with certain path.
however i don't like it because now the servlet will call the CookieManager.java.handleCookie will have a side effect I would rather it to return some kind of a response and further use it in my servlet wihtout having it effect its parameters that i'm passing into it.
anyone can suggest a solution which would both be elegant, no side effects, and excellent in performance?
thanks
You can make use of servlet filter. It would be well suited for your case. You can map your filter to URL pattern and write your code inside dofilter method. Filters are recommended if you want to have pre and post prcoess of request/response. Since you are doing preprocess for you request it would fit in your case. If is also loosely coupled, because you can remove it, modify it, or add another rule anytime without modifying the core servlet code.
One good solution is to use create a servlet which will act as a parent class for all other servlets.
Now in this servlet put this logic of cookie handling in a common function say handlecookie.
In your get and post APIs of this servlet first call this handleCookie and then service API of servlet (keep this empty)
In al child servlet classes you can only override the service class inherited from the parent class and things should work fine for you
Servlet filters are other solution that you can make use of.
Is there a way to get a list of all SOAP headers in a web method with plain JAX-WS? I know this can be done by using Metro specific classes (HeaderList hl = messageContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)). However I'm not sure if I can rely on having that implementation at runtime so I'd like to stick to JAX-WS.
I also know about the header attribute of the #WebParam annotation. I'd prefer not having to specify the header parameter there. The reason is that my web service has some IDs that are common to all web methods and this would pollute the interface. Also in case another ID comes along or one gets removed again (the spec is not final yet) I'd have to modify every single web method. Also there would be no reason anymore for using a header - it could be a normal method parameter.
The third way I know of is using a handler via #HandlerChain but then I have no way of connecting the headers with the executed web method. The IDs I mentioned are important for further processing - they are not just access control that can work independently of the method.
If you implement a request handler, you can store the headers in a thread local, static variable and implement some kind of access mechanism to it for your service method implementation.
From within a servlet, how can I tell if the servlet is being called by a RequestDispatcher("").include, or if it was called normally?
There should be a bunch of request attributes present, listed here:
http://www.caucho.com/resin-3.0/webapp/faq.xtp#forward-path
For example, request.getAttribute("javax.servlet.include.request_uri") should return a non-null value if an include is in progress.
I'm not sure you can tell directly in a request object, however you can (in servlet 2.4+) insert Filters based on whether the request was a request, a forward, or an include with a declaration in your web.xml.
The setup is described on this developerworks article.
You could, for example, use this technique to intercept includes destined for the URLs you are interested in, and add an attribute to the request which you could then see in your servlet.