Questions about spring reference statement and application context - spring

I have two primary doubts about spring:
When we get a bean from context, should we must use ways like :
context = new ClassPathXmlApplicationContext("applicationContext.xml");
Should it be called only via this explicit way?
I was thinking about that when the website start, this spring config file should also be read.
When we use tags of spring or other packages like jstl, etc. We should give the reference statement first like :
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
I was so curious about that, when the page is parsing, the web server do download this uri and use it in this page? But without internet, it seems also work. How it works, or why we must add this in the head part of a file.

It is indeed possible to get a bean from the Spring context that way, but it might be considered to be defeating the purpose of having a bean container with dependency injection. The goal of the container would be to provide the beans to your classes, so they don't need to instantiate or grab them directly from the context. See this short tutorial for a simple example of (xml-based) DI.
The uri attribute in a <%taglib> tag can be resolved locally if the tld is in your classpath under a certain specific path. See With JSP, does the taglib URI mean that my site is reliant on the URI resolving?.

Related

What is the right approach to process a Freemarker Template on the fly in Spring service bean?

I a few existing freemarker templates (ftl) in Spring MVC project. They are using standard spring tags (#spring.url, #spring.message and #spring.bind). While using standard approach of using FreemarkerConfig inside the servlet context (with ViewResolver) all of the templates work fine.
I also have some email templates which is programatically being created, but they are not using any spring tags or additional tlds.
The twist is, I have a task to use the regular template and process them using Freemarker Template class from a Service Bean. The service class have the find the template in the specified location ("/WEB-INF/views"), but it does not process the spring tags, and finds "spring" variable to null. I have set "auto_import" to "/spring.ftl as spring", but my understanding is it will only work within Web/servlet context? Am I using the right approach here? What is the best way to process a "Template" outside and how to expose the spring.tld or anyother.ltd for it? Appreciate your help / pointers!

Can I move entire web.xml to spring code base configuration? (WebApplicationInitializer)

My application will use mainly use code based configuration. From web.xml to Springs WebApplicationInitializer class I already moved: servlet, filters and mapping. However in web.xml have much more elements (such as error-page or welcome page: https://docs.oracle.com/cd/E13222_01/wls/docs81/webapp/web_xml.html). Which of those elements I can move to code and what are their equivalents?
Generally, yes, you should be able to get Java Config equivalents of all elements that you can set in the web.xml. In terms of converting individual elements, if you can give specifics, then we could find the JavaConfig equivalents.
Note that it's not always a 1-to-1 mapping. For example, with Spring Security, you have to define the "delegatingFilterProxy" filter in web.xml but the JavaConfig equivalent does this behind the scenes. Using Spring Security annotations triggers that behavior.
I recommend two things:
Read through the Spring JavaConfig guide if you haven't done so
If you're stuck on a particular element, search for " JavaConfig". Usually, you can find some useful information quickly that way.
For the welcome page follow these steps:
Under your application root, create a html file called index.html
In that declare a head section with the content: <meta http-equiv="Refresh" content="0; URL=anonymous/homepage.htm"/>
Now when you access your application using http://myapplication.com you will be automatically redirected to http://myapplication.com/anonymous/homepage.htm. This acts as your index/welcome page
For the error page follow these steps:
In the controller:
try
{
}
catch (Exception ex)
{
return new ModelAndView("error");
}
In views.properties (or equivalent) define a error page like:
error.(class)=org.springframework.web.servlet.view.JstlView
error.url=/WEB-INF/jsp/errorpage.jsp

pageContext.request.contextPath and generic linking

In reference to my older unanswered question, I have a further error / problem that is partially related to it.
generic linking, variables and paths in jsp
When I include my header.jsp like this:
<%#include file="/WEB-INF/view/jsp/common/header.jsp" %>
It works fine.
But does not if I do it like this:
<%#include file="${pageContext.request.contextPath}/view/jsp/common/header.jsp" %>
Error:
HTTP Status 500 - /WEB-INF/view/jsp/common/login/login.jsp (line: 8, column: 1) File "${pageContext.request.contextPath}/view/jsp/common/header.jsp" not found
The above with ${} is a proper way and thats what I had been doing in the past until I started using spring and spring security.
But I dont think its a problem of spring or spring security.
I really cant understand why WEB-INF has a weightage and
How can I make my links generic (ref my old stated question)
Actually, it's not the proper way in this case. The context path is not used for creating paths within the internals of your app, as in this case. Instead, it is used to generate URLs within the view layer, such as links, form URLs, and etc.
In this case, the following is correct:
<%#include file="/WEB-INF/view/jsp/common/header.jsp" %>
The include line above is referring to a resource that is packaged inside your war file. How would the context path, which is configured at the servlet container, have anything to do with the location of something packaged inside your war?
To recap, you only need to use ${pageContext.request.contextPath} to prefix URLs that are going to be placed in output to the client.

Get config setting in custom taglib using Spring "context-property-placeholder"

I'm creating a custom taglib, and would like to use some config options that are loaded via the underlying Spring framework using:
<context:property-placeholder location="classpath:config.properties" />
How would I get access to these variables in my taglib?
Thanks,
James.
The JSP taglibs have nothing in common with the Spring context's lifecycle, they're managed by the servlet container. This can complicate things a bit, for example: inject-dependency-into-a-taglib-class, how-to-write-tag-in-my-spring-project.
Since you're only mentioning the need for contents of the properties file, you could use plain old java.util.ResourceBundle (or, if you need more flexibility, Apache Commons' org.apache.commons.configuration.PropertiesConfiguration).
(One could also argue that requiring access to configuration in your tags indicates a design problem...)

JSP Including A Private Servlet

I have a servlet that responds to a URL and then forwards to a JSP in a typical MVC pattern.
Many pages share the same page head so in the JSP there is an include to head.jsp
head.jsp is placed inside WEB-INF so that it cannot be accessed directly.
Now I find that I need to add some control to the head. Rather than forwarding to WEB-INF/head.jsp and putting scriptlets in I would like to forward to a servlet instead.
How can I forward from the JSP to a servlet without mapping that servlet to a URL as I do not want to give direct access to this servlet.
Or to put it another way is there a servlet equivalent of WEB-INF to hide it from direct access? So the servlet can only be called via an include?
Rather than forwarding to WEB-INF/head.jsp and putting scriptlets in I would like to forward to a servlet instead.
It's indeed possible to do this (using <jsp:include> or a small scriptlet that dispatches), but I'm not sure whether this is really the best approach. The Servlet would either write directly to the response or would put some data in the request scope that the JSP can pick up later.
Writing directly to the response is a bit debatable today and for the other approach you don't need a Servlet at all.
The idiomatic way is to use some helper bean that contains the logic. The original Servlet you mentioned can put this bean into request scope, or you can use the <jsp:usebean> tag. Reference the data the helper bean prepared via expression language or very simple scriptlets.
So the servlet can only be called via an include?
If you still want to go this route, there might be an option of securing the Servlet behind a role and then giving the head.jsp a run-as role in web.xml:
<servlet>
<servlet-name>headInclude</servlet-name>
<jsp-file>/WEB-INF/head.jsp</jsp-file>
<run-as>
<role-name>SYSTEM</role-name>
</run-as>
</servlet>
disclaimer: I have never tried this myself, just pointing in a possible direction.

Resources