Default formView for SimpleFormController? - spring-mvc

Firstly I would like to say that I am quite new to Spring (in particular the MVC framework), and just trying to understand how everything works so please go easy on me.
I'm playing around with a dummy application that I've created, and I've created a simple login form that users can access via the /login.html bean. The bean definition is as follows:
<bean name="/login.html" class="test.controller.LoginController">
<property name="successView" value="list_messages.html" />
<property name="commandClass" value="test.domain.Login" />
<property name="commandName" value="login" />
</bean>
(the Login class is a simple object containing a username and password field with appropriate getters and setters).
The LoginController class does virtually nothing for now:
public class LoginController extends SimpleFormController
{
#Override
protected ModelAndView onSubmit(Object command, BindException errors) throws Exception
{
return new ModelAndView(new RedirectView(getSuccessView()));
}
}
Now I have one view resolver in my bean definition file, which goes as follows:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
To support my Login form I have a login.jsp file in my jsp directory.
My question is as follows: why does accessing /login.html redirect me to login.jsp? I have not specified a formView property for my form, so how does the view resolver know to redirect me to login.jsp?
Thanks in advance for any help!
Joseph.

When you do not specify The logical view name, Spring relies on DefaultRequestToViewNameTranslator, which is installed by default. So if your request is something like
http://127.0.0.1:8080/app/<LOGICAL_NAME_EXTRACTED_BY_VIEW_NAME_TRANSLATOR_GOES_HERE>.html
Have you seen <LOGICAL_NAME_EXTRACTED_BY_VIEW_NAME_TRANSLATOR> ??? So if your request is
http://127.0.0.1:8080/app/login.html
The logical name extracted by ViewNameTranslator is login which is supplied To viewResolver and Translated To
/jsp/login.jsp
Nothing else

Related

spring mvc model value with jsp tags

Here is what i have:
I am using JTable (http://www.jtable.org/) inside jsp pages, along with spring mvc model. I also have setup localization, all these work fine. Below i have part of my code, added what i consider as relevant as i am not sure... Please ask me as soon as you get some input for me
(will answer on monday as in weekend i doupt i can have pc access).
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:i18n/messages"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en_US"/>
</bean>
Here is what i need to do:
I need to create a jtable where fields, actions,etc come from server so that these are dynamic (check Dynamic creation of multilevel Javascript object for jQuery-jTable made from other user). In my case myobj will come from server as a string, i.e.
#RequestMapping(value = "/locales", method = RequestMethod.GET)
public ModelAndView testList(ModelAndView mv, final HttpServletRequest request) {
mv.setViewName("list");
mv.addObject("model",
"{\n" +
" title: '<spring:message code=\"table.users.users\"/>',\n" +
....
" fields: {\n" +
" ID: {\n" +
" key: true,\n" +
" list: false,\n" +
" create: false,\n" +
" edit: false\n" +
" },\n" +
" Name: {\n" +
" title: '<spring:message code=\"table.name\"/>',\n" +
" width: '15%',\n" +
...
This text you see above passed in the model of the controller will be created dynamically (using velocity engine,dynamic data,...)
list.jsp is as follows:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%# taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<tags:template>
<jsp:body>
<script>
$(document).ready(function() {
$('#ListContainer').jtable(${model});
$('#ListContainer').jtable('load');
});
</script>
<div id="ListContainer" style="width:99%;"></div>
</jsp:body>
</tags:template>
My problem is that although i have in my site setup localization et all, the tags i.e. ' are not rendered when these are inside the content of the controller's returned model. Is there a way to say to the Controller or the InternalResourceViewResolver to resolve the model's value as if it was a jsp?
I hope i made my problem clear and gave all that is needed to respond to me, if not please feel free to ask. I am afraid since i am still leaning i do not have either clear in my mind how all these bind together the only thing i know is that i need to have a dynamic/generic jtable list fully localized list.
I managed to work around my problem. Still not sure if this is the best solution but i thought to let you people know in case someone else needs same solution.
So here is how it goes, i have the following flow:
controller-->{Velocity engine}-->localized jtable configuration-->jsp
The controller gets the model and feeds it to a velocity template. Inside there i also feed (apart from my velocity template model):messageSource and localeResolver.
Wherever i have localization labels in velocity i write them as follows:
${messageSource.getMessage(${field.title}, $noArgs, ${field.title}, $locale)}
even when i need to pass some velocity model values which should be evaluated from velocity i use the macro #evaluate($table.name).
After velocity evaluation finishes i have the configuration of jtable ready and feed it to the jsp.
I will leave this question open for some more time in case someone can provide with a beter solution.

Spring Framework - How to change locale in controller

I am new to Spring, and currently confusing about localization.
I'm using the following code to get text from messages_jp.properties file.
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean>
And now I want to switch to text from messages_en.properties file, is there any ways to change locale in controller within if...else... block, not with using url params like "?lang=en", something like:
if (user.getLang() == 1) {
// set locale to en
} else {
// set locale to jp
}
Thanks in advance!
Try this one
<util:properties id="yourFileNameId" location="classpath:/yourFileName.properties"/>
In Controller
#Value("#{yourFileNameId['message_id']?:1}")
private int smalltext;

InternalResourceViewResolver to resolve both JSP and HTML together

I want org.springframework.web.servlet.view.InternalResourceViewResolver to resolve both JSP and HTML pages.
Is that possible?
You can configure an InternalResourceViewResolver something like this:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=""/>
</bean>
Where the WEB-INF/pages folder can contain both jsp and html pages and the suffix property is left empty.
Then in your controller, you can have methods that return html views and methods that return jsp views based on the suffix. For example, if index.html and index.jsp both exist in WEB-INF/pages you can do:
#RequestMapping("/htmlView")
public String renderHtmlView() {
return "index.html";
}
#RequestMapping("/jspView")
public String renderJspView() {
return "index.jsp";
}
However, as html pages are static and require no processing, you'd be better to use the <mvc:resources> tag rather than a view resolver for this type of page. See the docs for more info.

How to access subdir within images folder (getting 404)?

I've added a new subdir within my images folder and cannot get the new images to resolve.
Failed to load resource: ... 404 (Not Found)
http://localhost:8080/mywebapp/content/images/subdir/mysubdirimage.png
My directory structure:
src
-- main
--java
--webapp
--content
--images // <- these resolve
--subdir // <- new subdir...resolve fail for images
I have tried adding the following but does't work:
<mvc:resources mapping="/content/**" location="/content/" />
mvc-dispatcher-servelet.xml:
<mvc:annotation-driven/>
<mvc:default-servlet-handler />
<mvc:resources mapping="/content/**" location="/content/" /> //<-- Added this..no go!
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"><value>/WEB-INF/views/</value></property>
<property name="suffix"><value>.jsp</value></property>
</bean>
You are halfway there with the mvc-dispatcher-servlet line you added, but you need to change it to:
<mvc:resources mapping="/images/**" location="/content/images/" />
Also try changing the method in your controller where you are attempting to access the images to something like:
#RequestMapping(value = "/staticImages", method = RequestMethod.GET)
public String showImage() {
return "/images/subdir/mysubdirimage.png";
}
And finally, with the example above try the URL (as you were doing above):
http://localhost:8080/mywebapp/images/subdir/mysubdirimage.jpg
You should also be able to access the images through the #RequestMapping pattern defined in your controller. For example, using the example I gave you above, you would enter the URL:
http://localhost:8080/mywebapp/staticImages

Spring MVC 3, Interceptor on all excluding some defined paths

Is it possible to apply an interceptor to all controllers and actions, except some that are defined?
Just to be clear, I am not interested in applying an interceptor on a list of defined ones. I want to define those to exclude.
Thanks!
Since Spring 3.2 they added that feature with the tag
mvc:exclude-mapping
See this example from the Spring documentation:
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/admin/**"/>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/secure/*"/>
<bean class="org.example.SecurityInterceptor" />
</mvc:interceptor>
Here's the link to the doc
For java based configuration, from the docs
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleInterceptor());
registry.addInterceptor(new ThemeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
}
}
When configuring an interceptor, you can specify a path pattern. The interceptor will be invoked only for controllers which the path matches the interceptor path pattern.
ref: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-config-interceptor
But as you probably noticed it, the path pattern doesn't support exclusion.
So I think the only way is to code a blacklist of paths inside the interceptor. When the interceptor is invoked, retrieve the HttpServletRequest.getRequestURI() and check if the path is blacklisted or not.
You can build the blacklist inside a #PostConstruct annotated method of the interceptor, and so get the blacklisted path from a property file for instance.

Resources