Search code examples
springjspspring-mvcspring-web

Model Attribute in JSP not working after added JSTL View


I'm using Spring 4 Web MVC in this project. Please help me to see my configuration and the error I get below. Correct me if the way I configure is wrong. Thank you.

root-context.xml

<bean id="entityManagerFac" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" autowire="byName">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
        <list>
            <value>com.hannacch.admin.model</value>
        </list>
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</prop>
        </props>
    </property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
    <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=DBADMIN;" />
    <property name="username" value="sa" />
    <property name="password" value="@dmin" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFac" />
</bean>

<tx:annotation-driven />

<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<jpa:repositories base-package="com.hannacch.admin.repository" entity-manager-factory-ref="entityManagerFac"/>

servlet-context.xml

<annotation-driven />
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.hannacch.controller" />

<resources mapping="/resources/**" location="/resources/" />

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="viewClass" value="com.hannacch.Spring.JstlView" />
    <beans:property name="prefix" value="/WEB-INF/views/page/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

admin-context.xml

<annotation-driven />
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.hannacch.admin" />

<resources mapping="/resources/**" location="/resources/" />

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="viewClass" value="com.hannacch.Spring.AdminJstlView" />
    <beans:property name="prefix" value="/WEB-INF/views/admin/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

CreateUserController.java

@ModelAttribute("userCredential")
public UserCredential createModel() {
    return new UserCredential();
}

@RequestMapping(method = RequestMethod.GET)
public String createUser() {
    return "/admin/createUser";
}

@RequestMapping(value="/addUser", method = RequestMethod.POST)
public String doActions(@ModelAttribute UserCredential userCredential) {

    userCredential.setId(1);
    userCredentialService.createUserCredential(userCredential);

    return "/admin/createUser";
}

createUser.jsp

<form:form action="createUser/addUser" method="POST" commandName="userCredential">
<table>
<tr>
    <td><form:label path="username">Username</form:label></td>
    <td><form:input path="username" /></td>
</tr>
<tr>
    <td><form:label path="password">Password</form:label></td>
    <td><form:password path="password" /></td>
</tr>
<tr>
    <td colspan="2">
        <input type="submit" value="Submit"/>
    </td>
</tr>

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>adminServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/admin-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>adminServlet</servlet-name>
    <url-pattern>/admin/*</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Previously in my servlet-context.xml and admin-context.xml, I didn't set viewClass in both xml, the model attribute was working and able to let me save data into database. After I added in viewClass in servlet-context.xml and admin-context.xml, the code is not working and I get error below:

ERROR: org.springframework.web.servlet.tags.form.LabelTag - Neither BindingResult nor plain target object for bean name 'userCredential' available as request attribute
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'userCredential' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
at org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:130)
at org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:120)
at org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:90)
at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
at org.apache.jsp.WEB_002dINF.views.admin.createUser_jsp._jspx_meth_form_005flabel_005f0(createUser_jsp.java:224)
at org.apache.jsp.WEB_002dINF.views.admin.createUser_jsp._jspx_meth_form_005fform_005f0(createUser_jsp.java:169)
at org.apache.jsp.WEB_002dINF.views.admin.createUser_jsp._jspService(createUser_jsp.java:121)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:584)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:523)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:934)
at org.apache.jsp.WEB_002dINF.views.include.adminTemplate_jsp._jspService(adminTemplate_jsp.java:102)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:584)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:523)
at com.hannacch.Spring.AdminJstlView.renderMergedOutputModel(AdminJstlView.java:19)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:277)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

How can I solve this problem? What happen to my JSTLView?

AdminJSTLView.java

public class AdminJstlView extends InternalResourceView {

protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
    String dispatcherPath = prepareForRendering(request, response);

    request.setAttribute("adminContents", dispatcherPath.substring(dispatcherPath.lastIndexOf("/") + 1));

    RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/views/include/adminTemplate.jsp");
    requestDispatcher.include(request, response);
}

}


Solution

  • The error occured because of missing to expose the model object while overriding renderMergedOutputModel.

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        exposeModelAsRequestAttributes(model, request);
    
        String dispatcherPath = prepareForRendering(request, response);
    
        request.setAttribute("adminContents", dispatcherPath.substring(dispatcherPath.lastIndexOf("/") + 1));
    
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/views/include/adminTemplate.jsp");
        requestDispatcher.include(request, response);
    }