internal resource view resolver with multiple subfolders under jsp - spring-mvc

Hi I used Internal resource view resolver and my structure of jsp are like
jsp/adm, jsp/icon, jsp/iload, like
and my annotation based controller will return string value based on condition
my problem is jsp uder sub-folder is not resoled but it is under jsp folder is working
could any one please help me in this
he is my code:`
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
my controller code is
#RequestMapping("/icrl")
public String search() throws Exception
{
setMenuName(CommonConstants.ICRL);
return "pgiCRL";
}
#RequestMapping("/searchCodes")
public String searchCodes() throws Exception
{
String key=getSearchKey();
String query=getQuery();
Map<String, Object> searchKeys = new HashMap<String, Object>();
ArrayList<String> list=new ArrayList<String>();
if(query!=null||!query.isEmpty()){
searchKeys.put(CommonConstants.DIAGICD9, getDiaICD9());
searchKeys.put(CommonConstants.DIAGICD10, getDiaICD10());
searchKeys.put(CommonConstants.DIAGNOSIS, getDiagnosis());
searchKeys.put(CommonConstants.PROCEDURE, getProcedure());
searchKeys.put(CommonConstants.SURGICAL, getSurgical());
searchKeys.put(CommonConstants.SURGICAL9, getSurICD9());
searchKeys.put(CommonConstants.SURGICAL10, getSurICD10());
searchKeys.put(CommonConstants.REVENUE, getRevenue());
list= (ArrayList<String>) iCRLService.getSearchCodeList(query,searchKeys);
}
setSuggestions(list);
return CommonConstants.SUCCESS;
}
my view is depending on condition it may be success page and failure page so i need to fix the return value in controller because that is dynamic.
Thanks in advance

You need to define the subfolder name in the returning string value.
For Example, if your page "pgiCRL" is in admin subfolder then return "admin/pgiCRL".

Related

org.hibernate.validator.constraints not picking reloaded messages

I am trying to use Spring's ReloadableResourceBundleMessageSource for LocalValidatorFactoryBean so that when I update an error message it should reflect without requiring the server to be restarted. I am using Spring 4.1.4, hibernate-validator 4.3.2.Final.
Below are the code details -
context.xml -
<mvc:annotation-driven validator="validator" />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>file:../conf/fileapplication</value> <!-- Messages here will override the below properties file-->
<value>/WEB-INF/application</value>
</list>
</property>
<property name="cacheSeconds" value="10"></property> <!-- Will check for refresh every 10 seconds -->
</bean>
<bean name="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource">
<ref bean="messageSource"/>
</property>
</bean>
Model -
import org.hibernate.validator.constraints.NotBlank;
public class InputForm {
#NotBlank ( message = "{required.string.blank}")
String requiredString;
Controller -
#RequestMapping(value = "/check/string", method = RequestMethod.POST)
public String checkString(
#ModelAttribute("formModel") #Valid InputForm inputForm ,
BindingResult result, Model model, HttpServletResponse response,
HttpServletRequest request) {
if (result.hasErrors()) {
model.addAttribute("formModel", inputForm);
return "userInput";
}
// Do some backend validation with String
result.reject("string.not.valid",
"String is Invalid");
model.addAttribute("formModel", inputForm);
return "userInput";
}
application.properties (in /WEB_INF/ folder)
required.string.blank=Please enter the required string.
string.not.valid=Please enter a valid string.
fileapplication.properties (in /conf/ folder. Will override above file)
required.string.blank=You did not enter the required string. #Does not reflect when I change here
string.not.valid=You did not enter a valid string. #Reflects when I change here
Now the problem I am facing is, when I update "string.not.valid" in fileapplication.properties it reflects at runtime and I see the updated message. But when I update "required.string.blank" in fileapplication.properties it does not reflect at runtime.
Note that the overriding part is working fine for both messages upon application start up. But the "reloading" part is not working fine for "required.string.blank".
This is what I figured out based on my research - We need to create our own MessageInterpolator and add it as dependency to the validator instead of message source. Because when we add a messageSource as dependency, it is cached by default by the validator and any message reloads spring does won't take effect in the validator's cached instance of messageSource.
Below are the details:
In context.xml, add the custom MessageInterpolator as dependency to LocalValidatorFactoryBean instead of messageSource:
<mvc:annotation-driven validator="validator" />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>file:../conf/fileapplication</value> <!-- Messages here will override the below properties file-->
<value>/WEB-INF/application</value>
</list>
</property>
<property name="cacheSeconds" value="10"></property> <!-- Will check for refresh every 10 seconds -->
</bean>
<bean name="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="messageInterpolator">
<ref bean="messageInterpolator"/>
</property>
</bean>
<bean name="messageInterpolator"
class="com.my.org.support.MyCustomResourceBundleMessageInterpolator">
<constructor-arg ref="messageSource" />
</bean>
Create your custom MessageInterpolator by extending Hibernate's org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.
public class MyCustomResourceBundleMessageInterpolator extends
ResourceBundleMessageInterpolator {
public MyCustomResourceBundleMessageInterpolator(MessageSource messageSource)
{
// Passing false for the second argument
// in the super() constructor avoids the messages being cached.
super(new MessageSourceResourceBundleLocator(messageSource), false);
}
}
Model, Controller and properties file can be same as in the question.

Error while loading Velocity template in Spring MVC(org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource)

I am getting the
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource error. can some one help me to figure out the issue.I have attached my code below.Any help would be appreciated.Thank you.
I placed the .vm in the class path src folder.
Controller look like
#RequestMapping("/velocity")
public String velocity(final HttpServletRequest request, final HttpServletResponse response)
{
final VelocityEngine ve = new VelocityEngine();
ve.setProperty("resource.loader", "class");
ve.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
ve.init();
/* next, get the Template */
final Template t = ve.getTemplate("index.vm");
/* create a context and add data */
final VelocityContext context = new VelocityContext();
context.put("members", "sharat");
/* now render the template into a StringWriter */
final StringWriter writer = new StringWriter();
t.merge(context, writer);
final String Html = writer.toString();
return Html;
}
spring-servlet.xml
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value=""/>
<property name="suffix" value=".vm"/>
</bean>
Error:
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'index.vm'
org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474)
org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352)
org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514)
org.apache.velocity.app.VelocityEngine.getTemplate(VelocityEngine.java:373)
velocity.properties
resource.loader = class
file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = vm
file.resource.loader.cache = false
file.resource.loader.modificationCheckInterval = 0
You need to replace
resource.loader = class
with
resource.loader = file
Also, if you're in a webapp, you should check the WebappResourceLoader from the Velocity Tools subproject, which will help you specify a path relative to the root of the webapp. You can easily find online how to configure Spring with Velocity Tools.
Otherwise, you will have to specify an absolute path for the file.resource.loader.path property, or be sure that the current execution path of your webapp container contains a vm directory with your templates within.

Spring MVC Tiles Redirect Issue

I am using Spring MVC and Tiles.
When I try to use spring prefix "redirect:" for the redirection I get a servlet exception
- "Could not resolve view...".
Controller
RequestMapping("/SUPPORT.lz")
public String generateSupportView(HttpServletRequest request)
{
String url="http://"+request.getServerName()+":"+request.getServerPort()+"/APP";
AuthenticatedUser user = getUser();
/*
* Check if a user has the role for the page he is trying to access. If
* not redirect him to default page (home page).
*/
if (user.getRoles() != null && !user.getRoles().contains(new Role(0, Role.RoleType.SUPPORT)))
{
return "redirect:"+url;
}
return "support.tiles";
}
dispatcher-servlet.xml
<bean id="tilesViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver"
p:order="1"
p:viewNames="*.tiles"
p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView"/>
<bean id="nontilesViewResolver"
class="org.springframework.web.servlet.view.XmlViewResolver"
p:order="2"
p:location="/WEB-INF/app-nontiles-views.xml"/>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
p:definitions="/WEB-INF/app-tiles.xml"/>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="i18n"/>
Solution-
I added internal view resolver in disaptacher servlet.xml and issue got resolved.
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:order="3">
</bean>

How do I restrict route extensions in #RequestMapping paths for Spring MVC controllers?

I have a fairly simple task that I want to accomplish, but can't seem to find information for Spring MVC routing about it. I have a very simple controller that routes a path to a view:
#Controller
#RequestMapping(value = "/help")
public class HelpController {
private static final String HELP = "help";
#RequestMapping(method = RequestMethod.GET)
public String help(Model model, Locale locale) {
model.addAttribute("locale", locale);
return HELP;
}
}
I would like to throw a 404 if http://mysite.com/help.some.extension.is.entered, but Spring seems to resolve the example to /help. The javadoc says that the #RequestMapping annotation is just a servlet URI mapping, but I thought /help means it needs to be an exact match. Any clarification would be appreciated.
For Spring 4 it's pretty easy to solve:
<mvc:annotation-driven>
<mvc:path-matching suffix-pattern="false" />
</mvc:annotation-driven>
So you still can use mvc:annotation-driven for your config.
You can mention it in the #RequestMapping annotation
it is same as Servlet URL pattern only.
#Controller
public class HelpController {
private static final String HELP = "help";
#RequestMapping(value = "/help" method = RequestMethod.GET)
public String help(Model model, Locale locale) {
model.addAttribute("locale", locale);
return HELP;
}
#RequestMapping(value = "help/*" method = RequestMethod.GET)
public String helpWithExtraWords() {
return "error";
}
}
The best way I can think of is to configure your RequestMappingHandlerMapping explicitly to not consider suffixpaths, this way:
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="useSuffixPatternMatch" value="false"></property>
</bean>
However, if you have configured your Spring MVC using mvc:annotation-driven, this will not work, you will have to expand out the entire handlerAdapter definition, which is not that difficult to do, along these lines(this is not complete, you can look through org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser for the entire definition):
<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="conversionService" ref="conversionService"></property>
<property name="validator">
<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
</property>
</bean>
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</list>
</property>
</bean>
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="useSuffixPatternMatch" value="false"></property>
</bean>
With Spring 3.0.X You can use the useDefaultSuffixPattern property.
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="useDefaultSuffixPattern" value="false" />
</bean>
You will need to remove </mvc:annotation-driven>
Refer URL Pattern Restricting in SPRING MVC

How to deserialize xml using XStream in spring mvc

Im receiving this
<header><h1>001</h1><h2>002</h2></header>
my dispatcher looks like this
<bean id="annotatedMarshaller" class="org.springframework.oxm.xstream.AnnotationXStreamMarshaller">
<property name="annotatedClasses">
<list>
<value>someClasses</value>
<value>someClasses</value>
<value>someClasses</value>
</list>
</property>
</bean>
And here I try to use the unmarchal method from XstreamMarshaller and return the Object to cast
public static Object deserializeXml(String xml) {
StringReader sr =new StringReader(xml);
StreamSource ss=new StreamSource(sr);
Object o=null;
try {
o = xStreamMarshaller.unmarshal(ss);
} catch (XmlMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return o;
}
The problem came when I realized that the unmarshal method marshals the given object to a given javax.xml.transform.Result and not a simple String as the fromXml method from XStream.
thanks to THIS i figured out how to get a Result Object from a String, but not sure if is the best way to do it.
Totally agree with thought that spring should handle all marshaling/unmarshalling stuff.
Everything you need is to declare XStreamMarshaller as one of message converters.
That can be achieved via mvc:annotation section:
<mvc:annotation-driven>
<mvc:message-converters>
<!-- Your XStream converter. -->
</mvc:message-converters>
</mvc:annotation-driven>
or via AnnotationMethodHandlerAdapter:
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<!-- Your XStream converter. -->
</list>
</property>
</bean>

Resources