Hi im wondering would it be possible to create global interceptor and set locale there.
I have urlrewrite rules to rewrite /fr/* to /*?siteLang=fr
I see examples how to set locale based on parameter but they all are the same and require me to use url mappings. Is it possible to do it globally so that locale interceptor gets called on each request no matter what controller is it for?
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="siteLang"/>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor"/>
</list>
</property>
<property name="mappings">
<value>
/*=dispatchController
</value>
</property>
</bean>
There is no such thing as dispatchController in my xml so i cant use it but idea would be to intercept everything (in whatever way).
i would basically like to have urls with locale at the beginning of uri followed by the application bit like
/fr/user/details
/de/products/hifi
etc
different controllers using the same convention of rewriting url and never using siteLang for controller specific reasons.
Thanks
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>
Related
I am using Spring MVC, and freemarker as my view resolver, (not that that matters) I have multiple template loaders defined like this:
<bean id="urlTemplateLoader" class="com.URLTemplateLoader">
<property name="baseUrl" value="http://xxxx:8080/ftl/"/>
</bean>
<bean id="defaultTemplateLoader" class="com.WebappTemplateLoader">
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
</bean>
<bean id="multiTemplateLoader" class="freemarker.cache.MultiTemplateLoader">
<constructor-arg>
<list>
<ref bean="urlTemplateLoader"/>
<ref bean="defaultTemplateLoader"/>
</list>
</constructor-arg>
</bean>
this is designed to check a CMS server first, then use the local file. The view resolver is defined like this:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="preTemplateLoaders" ref="multiTemplateLoader"/>
<property name="freemarkerSettings">
<props>
<prop key="default_encoding">UTF-8</prop>
<prop key="localized_lookup">false</prop>
<prop key="date_format">yyyy-MM-dd</prop>
<prop key="template_update_delay">0</prop>
</props>
</property>
</bean>
Now the problem is that if the file is NOT on the remote server when it firsts looks for it, it never checks again until the server is re-started. I set the template_update_delay to 0, so once it is there, any time I update it, it automatically pulls the new one, which is great, -- but how do I get it to check again if it is not there in the first place?
As the JavaDoc of MultiTemplateLoader says:
On every request, loaders are queried in the order of their appearance in the array of loaders provided to the constructor. However, if a request for some template name was already satisfied in the past by one of the loaders, that Loader is queried first (a soft affinity).
I will add a sticky property to it (which enables/disables "soft affinity") in 2.3.24 (expected in early March), but I can't change its default until 3.0.0 or something like that. Meanwhile, you can do that in a custom TemplateLoader (copy-paste the source code of MultiTemplateLoader and just drop the affinity part from it... should be easy).
I'm trying to configure Spring MVC to have the following scheme :
any url starting with "{context}/resources" should be cacheable
any other url should not be cacheable (in my case, everything by "resources" are dynamic pages )
The first part is pretty easy using mvc:resource :
<mvc:resources mapping="/resources/**" location="..." cache-period="3600"/>
I'm kinda lost for the second part.
By default, it seems like the "dynamic resources" have no cache-related info (no cache-control header, no pragma, etc...). Some browsers might cache things (FF), some might not (Chrome), which is understanable.
There are many posts about how one can use a combinason of and WebContentInterceptor to make some pages cacheable :
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/foobar/**"/>
<bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds" value="0"/>
<property name="useExpiresHeader" value="true"/>
<property name="useCacheControlHeader" value="true"/>
<property name="useCacheControlNoStore" value="true"/>
</bean>
</mvc:interceptor>
</mvc:interceptors>
However in my case this is not useable as such, since I don't have a path expression to match (exclusion is notoriously impossible).
So is there a way I can express this :
* do what mvc:resources do for resources
* do "something" for all other pages ?
The only alternative I can see would be to write a custom Interceptor which would check whether somehing is a resource, but that sounds a bit strange not to be able to define cache properties globally.
Thanks
Spring MVC behaves just the way you want it. The WebContentInterceptor intercepts and adds cache-control only to the requests for text/html resources.
The way to do it for all urls is to leave <mvc:mapping> out of the configuration:
<mvc:interceptors>
<bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds" value="0"/>
<property name="useExpiresHeader" value="true"/>
<property name="useCacheControlHeader" value="true"/>
<property name="useCacheControlNoStore" value="true"/>
</bean>
</mvc:interceptor>
Also, because <mvc:interceptors> & <mvc:resources> are independent, any particular order of those two tags is not important (unlike suggested in the answer here).
I am on a project using Spring 3.x MVC, and have implemented our controllers using annotations. We recently have a requirement to implement HandlerInterceptors, to which I have had some problems. When I specify in my configuration (dispatcher-sevlet.xml), the interceptor
<bean id="myInterceptor" class="com.myProject.controllers.MyInterceptor" />
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list><ref bean="myInterceptor"/></list>
</property>
</bean>
then all is well, that is, any URL matches hits the myInterceptor code. When I try to add
<property name="mappings">
<props>
<prop key="/addFile.request">myFileController
</prop>
</props>
</property>
then I never hit the myInterceptor code...I have also tried to implement the above mapping code using #RequestMapping annotations.
It's easier to use the <mvc:interceptors> tag to configure interceptors if you're using annotation-based configuration.
E.g
<mvc:interceptors>
<!-- This runs for all mappings -->
<bean class="my.package.GlobalInterceptor"/>
<mvc:interceptor>
<!-- This one only runs for a specific URL pattern -->
<mvc:mapping path="/admin/*"/>
<bean class="my.package.AdminInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
What is a simple way to resolve the path to a JSP file that is not located in the root JSP directory of a web application using SpringMVCs viewResolvers? For example, suppose we have the following web application structure:
web-app
|-WEB-INF
|-jsp
|-secure
|-admin.jsp
|-admin2.jsp
index.jsp
login.jsp
I would like to use some out-of-the-box components to resolve the JSP files within the jsp root folder and the secure subdirectory. I have a *-servlet.xml file that defines:
an out-of-the-box, InternalResourceViewResolver:
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
a handler mapping:
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index.htm">urlFilenameViewController</prop>
<prop key="/login.htm">urlFilenameViewController</prop>
<prop key="/secure/**">urlFilenameViewController</prop>
</props>
</property>
</bean>
an out-of-the-box UrlFilenameViewController controller:
<bean id="urlFilenameViewController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController">
</bean>
The problem I have is that requests to the JSPs in the secure directory cannot be resolved, as the jspViewResolver only has a prefix defined as /jsp/ and not /jsp/secure/.
Is there a way to handle subdirectories like this? I would prefer to keep this structure because I'm also trying to make use of Spring Security and having all secure pages in a subdirectory is a nice way to do this.
There's probably a simple way to acheive this but I'm new to Spring and the Spring MVC framework so any pointers would be appreciated.
I haven't been able to discover the exact solution to the question I asked but I do have a workaround that suits my particular requirements. The problem seems to lie in the hander mapping. If specified as in the example in the post, any requests to pages in the secure folder result in a failed attempt to locate the actual JSP file in the /WEB-INF/JSP/ folder when of course the actual file is located in /WEB-INF/jsp/secure/.
However, if specified like so:
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login.htm">loginFormController</prop>
<prop key="**/*.htm">urlFilenameViewController</prop>
</props>
</property>
</bean>
Then all the pages are resolved correctly. A request to /login.html will go to a specific form controller but requests to all other pages, no matter whether they are in the root JSP directory or a sub directory will be found. For me this is fine because what I was really looking for was a way to avoid specifiying a controller for every page in the application (hmmm... perhaps I should have made that clear in the first post - and perhaps there are better ways to do this anyway(?)) . The **/*.htm acts as a catch-all case and any pages that I want handled by a different controller can be specified explicitly above this property, as demonstrated by /login.htm.
Try with UrlFilenameViewController or return new ModelAndView("secure/login");
You can try giving names of the views in the Controller like
<property name="formView" value="secure/admin"/>
<property name="successView" value="secure/admin2"/>
having prefix and suffix mapped as below
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
This will eventually map to /WEB-INF/jsp/secure/admin.jsp and /WEB-INF/jsp/secure/admin2.jsp
You need to set the alwaysUseFullPath property in in the Handler to true:
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
...
<property name="alwaysUseFullPath" value="true" />
</bean>
This will force the handler to use the '/secure/' part of the URI and then the resolver will include it when looking for a JSP in WEB-INF/jsp.
It seems like this ought to work, according to the docs:
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/web/servlet/mvc/UrlFilenameViewController.html
The configs you have shown seem to match up with the examples in the doc. If your Spring MVC dispatcher servlet is mapped to "/" then requests to "{context}/secure/whatever.jsp" should get translated to view name "secure/whatever". Maybe it has something to do with the "**" wildcard? Or maybe some of your other configs are not right? Can you include the portion of your web.xml where you set up your Spring dispatcher servlet and also include the full paths you're requesting in your browser?
Another way to find the problem would be to to download the Spring MVC source code and include it in your app, then use a debugger to see exactly what is going on in both the SimpleUrlHandlerMapping and UrlFilenameViewController beans to try to pinpoint the error. You should be able to pretty quickly determine where things are going wrong that way.
You need to set the property as follows:
<property name="prefix" value="/WEB-INF/jsp/"/>
and then you can access the URI secure/admin1.jsp
All sub folders can be accessed by using wild card in prefix
From controller you can simply return jsp name as string and the jsp will be displayed even if it is under sub folders of /WEB-INF/jsp/ like /WEB-INF/jsp/abc
Is it possible to have multiple resource bundles in spring mvc?
I want to separate my resource bundles for example one for errors, another for global messages, other for image names etc. so I don't have just one very big file
I'm using this
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean>
But here i can just specify 1 resource, can I use more?
You can just pass in a list using the setBasenames() method like this:
<beans>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>images</value>
<value>errors</value>
<value>globalMsgs</value>
</list>
</property>
</bean>
</beans>