Thymeleaf View not recognizing the specified action view - spring-mvc

I am facing an issue with viewresolver. Thymeleaf viewresolver not picking up the specified view in my controller action method and it is taking action name as view path instead.
Below is my thymeleaf configuration and controller code.
Controller :
#ModelAttribute("user")
#RequestMapping(method = RequestMethod.POST, value = "/register")
public String register(Model model, #Valid User user, BindingResult result, HttpServletRequest request, final Locale locale) {if (result.hasErrors()) {
List<ObjectError> errors = result.getAllErrors();
for (ObjectError error : errors) {
log.error("Errors are :: " + error.getDefaultMessage());
}
return "registration/indexed";
}else{------my operations------return "profile/index"}}
thymeleaf config..
<!-- THYMELEAF: Template Resolver for email templates -->
<bean id="emailTemplateResolver"
class="org.thymeleaf.templateresolver.ClassLoaderTemplateResolver">
<property name="prefix" value="mail/" />
<property name="templateMode" value="HTML5" />
<property name="order" value="2" />
<!-- Template cache is true by default. Set to false if you want -->
<!-- templates to be automatically updated when modified. -->
<property name="cacheable" value="true" />
</bean>
<!-- Thymeleaf template resolver -->
<bean id="webTemplateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
<property name="order" value="1" />
</bean>
<!-- THYMELEAF: Template Engine (Spring3-specific version) -->
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolvers">
<set>
<ref bean="emailTemplateResolver" />
<ref bean="webTemplateResolver" />
</set>
</property>
</bean>
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="order" value="1" />
<property name="characterEncoding" value="UTF-8" />
</bean>
But my Thymeleaf not recognizing "registration/index" and it is searching for "registration/register"
Would anybody please suggest what I have to do??
Thanks & Regards,
Gupta Katakam

Finally I figured out the problem. The problem is due to #ModelAttribute("user") . When I removed this line on top of my action method the problem got resolved.
Thanks & Regards,
Gupta Katakam

Related

Configuring MyBatis with Spring MVC for multiple datasources

I have been trying to configure MyBatis with Spring MVC to work with multiple databases. I have a page which is trying to connect to one of the DB's to fetch data, so that it can be populated into the drop-down boxes.
Now I am not sure what is wrong with this configuration, but I am receiving the following error:
]] Root cause of ServletException. org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLException: ORA-06576: not a valid function or procedure name
I am providing the XML file here for your reference
<bean id="dataSource1"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#1.1.2.5:1529:DITOS" />
<property name="username" value="return" />
<property name="password" value="return" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="p.com.ent.appl.return.dev.dao,p.com.ent.appl.return.dep.dao,p.com.ent.appl.return.dao.otheruser" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1" />
</bean>
<!-- Declare a transaction manager -->
<bean id="cashReturnTx"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource1" />
</bean>
<!-- define the SqlSessionFactory, notice that configLocation is not needed
when you use MapperFactoryBean -->
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
<!-- <property name="mapperLocations" value="classpath:/com/vrn/ent/dev/daoxml/*.xml"
/> -->
<property name="mapperLocations"
value="classpath*:/p/com/ent/appl/return/**/daoxml/*.xml" />
</bean>
<bean id="sqlSession1" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory1" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#4.24.80.15:1522:LM" />
<property name="username" value="RETURN" />
<property name="password" value="OWNER" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="p.com.ent.appl.return.dev.dao,p.com.ent.appl.return.dep.dao,p.com.ent.appl.return.dao.otheruser" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<bean id="otherUserTx"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- define the SqlSessionFactory, notice that configLocation is not needed
when you use MapperFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
<!-- <property name="mapperLocations" value="classpath:/com/vrn/ent/dev/daoxml/*.xml"
/> -->
<property name="mapperLocations"
value="classpath*:/p/com/ent/appl/return/**/daoxml/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
</beans>
According to the exception: BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLException: ORA-06576: not a valid function or procedure name, a DB is hit.
Read about error ORA-06576.
Issue is likeky be related to how the procedure is called. Right way is { CALL MyProcedure (#arg0, #arg1) }
Configuration shows that same mappers may be used with both datasources, what happens then if target schemas are different?

How to execute a spring batch job by clicking on a button in a jsp page?

I'm a newbie in spring batch and spring Mvc, and I want that a batch job (which extracts data from a database and writes it in another database) is executed from a jsp page by clicking on a button (or a link if it's possible) I'm using spring Mvc. This is my job configuration:
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseType" value="oracle" />
</bean>
<bean id="itemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader"
scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="select id,name,qual from users" />
<property name="rowMapper">
<bean class="tn.com.spring.UserRowMapper" />
</property>
</bean>
<bean id="oracleitemWriter"
class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
insert into users2(id,name,qual)
values (:id,:name,:qual)
]]>
</value>
</property>
<property name="itemSqlParameterSourceProvider">
<bean
class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
</property>
</bean>
<batch:job id="Job" job-repository="jobRepository">
<batch:step id="step1">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="itemReader" writer="oracleitemWriter"
commit-interval=" 10">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
<jdbc:initialize-database data-source="dataSource">
<jdbc:script
location="org/springframework/batch/core/schema-drop-oracle10g.sql" />
<jdbc:script location="org/springframework/batch/core/schema-oracle10g.sql" />
</jdbc:initialize-database>
and this is my job controller (I found it in the net but still not working!)
#Component
#Controller()
public class JobController {
#Autowired
#Qualifier("JobLauncher")
private JobLauncher jobLauncher;
#Autowired
#Qualifier("Job")
private Job job;
#RequestMapping(value = "/job")
public void job() {
try {
JobExecution execution = jobLauncher.run(job, new JobParameters());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
and here is the button
<form action=" <%=application.getContextPath()%>/job" method="get">
<input type="submit" value="execute My job" />
</form>
Could you please help me ? Whats's missing in my configuration?
I'm confused !
Thanks in advance.
As a solution for this problem, I have made this javascript code which will invoke the execution of the job :
$(function() {
$('#JobBtn').click(function() {
$.get('${batchJobUrl}');
});
});
and in the jsp page you need to specify the Id of the button writen in the javascript code:
<input type="button" value="execute job " id='JobBtn' class="btn" />
I Hope it will help someOne..

How can a Spring Webflow application be configured to use Xslt to render its viewstates

I would like my Spring Webflow app to render its views using XSLT. I managed to get a pure Spring MVC app to render with xslt by configuring an XSLTviewresolver and a controller method that returned an already prepared xml as a source.
But I'm not sure how to apply that to the webflow app.
I've added the configuration for the XSLT view resolver and set the view state to the xsl, then I call the controller method that returns the xml source in the on-render of the view state.So far I only get the xsl back as the output and not the transformed xml or even the raw xml.
EDIT
flow.xml-full
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
<view-state id="messageChoice" view="start1">
<transition on="chooseA" to="messageA"/>
<transition on="chooseB" to="messageB"/>
</view-state>
<view-state id="messageA" view="messageA">
<transition on="start" to="messageChoice"/>
</view-state>
<view-state id="messageB" view="xsltview">
<on-render>
<evaluate expression="sampleController.viewXSLT(externalContext.getNativeRequest(),externalContext.getNativeResponse())" result="requestScope.xmlSource"/>
</on-render>
<transition on="start" to="messageChoice"/>
</view-state>
<end-state id="finish"/>
</flow>
controller-snippet
#RequestMapping(value="/viewxslt")
public ModelAndView viewXSLT(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// builds absolute path of the XML file
String xmlFile = "/WEB-INF/xml/thexml.xml";
String contextPath = request.getSession().getServletContext().getRealPath(xmlFile);
String xmlFilePath = ""+contextPath + File.separator + xmlFile;
Source source = new StreamSource(new File(contextPath));
// adds the XML source file to the model so the XsltView can detect
ModelAndView model = new ModelAndView("xsltview");
model.addObject("xmlSource", source);
return model;
}
EDIT
flow-config-full
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
<context:annotation-config />
<context:component-scan base-package="com.genkey.derek" />
<mvc:view-controller path="/start" />
<mvc:view-controller path="/messageHome" />
<mvc:resources location="/" mapping="/resources/**" />
<faces:resources />
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
<property name="order" value="3" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean id="xsltviewresolver" class="org.springframework.web.servlet.view.xslt.XsltViewResolver">
<property name="order" value="1"/>
<property name="sourceKey" value="xmlSource"/>
<property name="viewClass" value="org.springframework.web.servlet.view.xslt.XsltView"/>
<property name="viewNames">
<array>
<value>xsltview</value>
</array>
</property>
<property name="prefix" value="/WEB-INF/xsl/" />
<property name="suffix" value=".xsl" />
</bean>
<bean id="viewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers">
<list>
<ref bean="xsltviewresolver"/>
<ref bean="faceletsViewResolver" />
</list>
</property>
</bean>
<bean id="faceletsViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".xhtml" />
<property name="order">
<value>2</value>
</property>
</bean>
<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" >
<webflow:flow-location path="WEB-INF/flows/startFlow.xml"/>
</webflow:flow-registry>
<faces:flow-builder-services id="flowBuilderServices" view-factory-creator="viewFactoryCreator" development="true" />
<bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>
</beans>

Shiro with Spring MVC Wildcard permissions not working

I have couple of permissions as:
inventory:po:view
inventory:po:create
inventory:po:update
In the JSP, below works:
<shiro:hasPermission name="inventory:po:create">
<li><a href='<c:url value="/inventory/document/viewDocument?doctype=2" />'>Purchase Order</a></li>
</shiro:hasPermission>
However, below doesn't.
<shiro:hasPermission name="inventory:po:*">
</shiro:hasPermission>
Shiro Version is 1.2.1. I also tried using the subject.isPermitted() call in and that doesn't work too.
I'm sure this is supposed to be pretty straight forward, but is there anything I miss in the configuration to enable wildcard support ? Please advice.
Shiro Configuration:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Security Manager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="jdbcRealm" />
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- Caching -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManager" ref="ehCacheManager" />
</bean>
<bean id="ehCacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
<bean id="sessionDAO"
class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO" />
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO" />
</bean>
<!-- JDBC Realm Settings -->
<bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
<property name="name" value="jdbcRealm" />
<property name="dataSource" ref="dataSource" />
<property name="authenticationQuery"
value="SELECT password FROM system_user_accounts WHERE username=? and status=10" />
<property name="userRolesQuery"
value="SELECT role_code FROM system_roles r, system_user_accounts u, system_user_roles ur WHERE u.user_id=ur.user_id AND r.role_id=ur.role_id AND u.username=?" />
<property name="permissionsQuery"
value="SELECT code FROM system_roles r, system_permissions p, system_role_permission rp WHERE r.role_id=rp.role_id AND p.permission_id=rp.permission_id AND r.role_code=?" />
<property name="permissionsLookupEnabled" value="true"></property>
<property name="cachingEnabled" value="true" />
</bean>
<!-- Spring Integration -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<!-- Enable Shiro Annotations for Spring-configured beans. Only run after
the lifecycleBeanProcessor has run: -->
<bean id="annotationProxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor" />
<bean id="authorizationAttributeSourceAdvisor"
class="org.apache.shiro.sprinemphasized textg.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<!-- Secure Spring remoting: Ensure any Spring Remoting method invocations
can be associated with a Subject for security checks. -->
<bean id="secureRemoteInvocationExecutor"
class="org.apache.shiro.spring.remoting.SecureRemoteInvocationExecutor">
<property name="securityManager" ref="securityManager" />
</bean>
<!-- Passthrough for Login page -->
<bean id="passThruLogin" class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter">
<property name="loginUrl" value="/login" />
</bean>
<!-- Shiro filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="successUrl" value="/dashboard" />
<property name="unauthorizedUrl" value="/error" />
<property name="filters">
<map>
<entry key="authc" value-ref="passThruLogin" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
<!-- !!! Order matters !!! -->
/authenticate = anon
/login = anon
/logout = anon
/error = anon
/static/** = anon
/** = authc
</value>
</property>
</bean>
The " * " isn't a wildcard in shiro's permission checking, on the contrary it means "requires all values".
You should assert a wildcard right of your own (read is usually a good default wildcard permission) and be explicit on the permission check.
On the contrary '*' means 'GRANT the user all rights', which got you confused with imho.
From Check Permissions part of shiro's documentation about permission
if ( SecurityUtils.getSubject().isPermitted("printer:print") ) {
//print the document
}
Therefore, this is an incorrect check. What if the current user does not have the ability to print to any printer, but they do have the ability to print to say, the lp7200 and epsoncolor printers. Then the 2nd example above would never allow them to print to the lp7200 printer even though they have been granted that ability!

i18n with Spring MVC, skip RequestMapping

I have set up i18n to my web app using Spring.It works fine.But I have a problem.When I click link to different language,from, lets say edit_user page. The request url is generated as '/edit_user.htm?lang=de'.Controller class receives this request and run editUser method based on #RequestMapping(value = { "edit_user" }). How to avoid this from happening.I just want my web app to be able to simply change the locale without reaching controller class methods when clicked on "change language links". My spring-config-servlet.xml is as following.
<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" />
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate" />
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="pretty" value="text/html" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
</constructor-arg>
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
....
</property>
<property name="defaultErrorView" value="errorPage" />
</bean>
Hm... Interesting.
UserController class receives this request:
en | de
for URL http://www.example.com/AppName/User/edit_user.htm?lang=de and run editUser method.
But you can change your links to:
EN | DE
and now when user click link to different language HomeController class receives request /?lang=de, web app change the locale and redirect user to the root page http://www.example.com/AppName/?lang=de.
Is this behavior acceptable for your application?
Otherwise I guess you have to filter request params for all controller classes if you want to find another solution.

Resources