spring3 jsp頁面使用報錯,附連接數據庫的spring MVC annotation 案例

在寫一個使用spring3 的form標籤的例子時,一直報錯,錯誤信息爲:java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute 。具體信息爲:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
	at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
	at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:174)
	at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
	at org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:129)
	at org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:119)
	at org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:89)
	at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
	at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
	at org.apache.jsp.WEB_002dINF.jsp.register_jsp._jspx_meth_sf_005flabel_005f0(register_jsp.java:255)
	at org.apache.jsp.WEB_002dINF.jsp.register_jsp._jspService(register_jsp.java:140)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:662)

在網上找了好長時間都不是原因所在,一直在想form標籤中的modelAttribute是怎麼跟project中相應的類聯繫在一起的,同事說是根據<form:input path="field"/>中的path attribute跟相應類中的field對應起來,由spring像注入一樣給每個field賦值。所以一直在JSP頁面查找原因,網上找的也都是改JSP頁面,結果還是沒有解決掉。

錯誤信息是“對於bean name 'xxxx' 既沒有BindingResult也沒有普通的目標對象可以用來作爲請求屬性”。突然想到在進入form表單頁面之前,要有一個'xxxx'對象纔可以在表單的標籤中識別出來,所以在進入該JSP頁面之前的Controller類裏面相應的方法裏面加上一個'xxxx'的對象。解決如下:

return new ModelAndView("register").addObject(new User());
已經驗證這樣修改之後就不會報錯。

例子的結構如圖:


web.xml 的內容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>springMVCForm</display-name>

	<servlet>
		<servlet-name>springMVCForm</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>springMVCForm</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/springMVCForm-servlet.xml</param-value>
	</context-param>

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

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

springMVCForm-servlet.xml 的內容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
	http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<mvc:annotation-driven />

	<context:component-scan base-package="org.spring.wayne" />

	<bean id="config"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:db-config.properties</value>
			</list>
		</property>
	</bean>

	<!-- 獲取數據源 -->
	<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
		<property name="driverClassName">
			<value>${db.dirverClass}</value>
		</property>
		<property name="url">
			<value>${db.url}</value>
		</property>
		<property name="username">
			<value>${db.username}</value>
		</property>
		<property name="password">
			<value>${db.password}</value>
		</property>
	</bean>

	<bean name="namedParameterJdbcTemplate"
		class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dataSource" />
	</bean>
	<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg ref="dataSource" />
	</bean>

	<bean
		class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

	<bean
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

	<!-- 對模型視圖名稱的解析,即在模型視圖名稱添加前後綴,在requestmapping輸入的地址後自動調用該類進行視圖解析 -->
	<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/" /><!-- 跳轉頁面的前綴路徑 
			如 /web-inf/jsp/ -->
		<property name="suffix" value=".jsp"></property><!-- 跳轉頁面後綴 如 helloWorld.jsp -->
	</bean>
</beans>

db-config.properties的內容:

db.url= jdbc:mysql://localhost:3306/springmvcdb?useUnicode=true&characterEncoding=utf8

db.username=root

db.password=

db.dirverClass= com.mysql.jdbc.Driver

UserDao.class的內容:

package org.spring.wayne.dao;

import org.spring.wayne.dao.basic.BasicDao;

@Repository
public class UserDao extends BasicDao {

	public void addUser(User user) {
		String SQL = "INSERT INTO TBL_USER(USERNAME ,PASSWORD) VALUES('" + user.getUserName() + "' ,'"
				+ user.getPassword() + "')";
		getJdbcTemplate().execute(SQL);
	}

}

BasicDao.class的內容:

package org.spring.wayne.dao.basic;

import org.springframework.beans.factory.annotation.Autowired;

public class BasicDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
		return namedParameterJdbcTemplate;
	}

	public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
		this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
	}
}

UserService.class的內容:

package org.spring.wayne.service;

import org.spring.wayne.web.form.User;

public interface UserService {

	public void addUser(User user);

}

UserServiceImpl.class的內容:

package org.spring.wayne.service.impl;

import org.spring.wayne.dao.UserDao;
@Service
public class UserServiceImpl implements UserService {
	@Autowired
	private UserDao userDao;

	@Override
	public void addUser(User user) {
		userDao.addUser(user);
	}

}

RegController.class的內容:

package org.spring.wayne.web.controller;

import javax.validation.Valid;

@Controller
public class RegController {

	@Autowired
	private UserService userService;

	@RequestMapping("/register.do")
	public String handler(@ModelAttribute("user") @Valid User user, BindingResult result, Model model) {
		if (!result.hasErrors()) {
			model.addAttribute("userName", user.getUserName());
			model.addAttribute("password", user.getPassword());
			userService.addUser(user);
			return "welcome";
		} else
			return "register";
	}
}

WelcomeController.class的內容:

package org.spring.wayne.controller;

import org.spring.wayne.web.form.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class WelcomeController {

	@RequestMapping("/welcome.do")
	public ModelAndView handler() {
		return new ModelAndView("register").addObject(new User());
	}
}
User.class的內容:

package org.spring.wayne.web.form;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

public class User {

	private String errors;

	@NotNull
	@NotEmpty(message = "This cannot be null")
	@Size(min = 4, max = 6, message = "length is wrong")
	private String userName;

	@NotNull
	@NotEmpty
	@Size(min = 6, max = 10)
	private String password;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getErrors() {
		return errors;
	}

	public void setErrors(String errors) {
		this.errors = errors;
	}
}

index.jsp的內容:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
    + request.getServerName() + ":" + request.getServerPort()
    + path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Index Page</title>
</head>
<body>
	<h3>
		<a href="<%=basePath %>welcome.do">Click here to start</a>
	</h3>
</body>
</html>

register.jsp的內容:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Register Page</title>
<script type="text/javascript">
	function doSubmit() {
		var sf = document.getElementById("sf");
		sf.submit();
	}
</script>
<style type="text/css">
.errors {
	font-size: 12px;
	color: red;
}
</style>
</head>
<body>
	<sf:form id="sf" method="POST" modelAttribute="user"
		action="register.do">
		<sf:errors path="errors" />
		<fieldset>
			<legend>Register</legend>
			<table cellspacing="0">
				<tr>
					<td><sf:label path="userName">UserName:</sf:label>
					</td>
					<td><sf:input path="userName" />
					</td>
					<td><sf:errors path="userName" class="errors" />
					</td>
				</tr>
				<tr>
					<td><sf:label path="password">Password:</sf:label>
					</td>
					<td><sf:password path="password" />
					</td>
					<td><sf:errors path="password" class="errors" />
					</td>
				</tr>
				<tr>
					<td colspan="2"><input type="button" value="Submit"
						onClick="doSubmit()">
					</td>
				</tr>
			</table>
		</fieldset>
	</sf:form>
</body>
</html>

welcome.jsp的內容:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Welcome Page</title>
</head>
<body>
	Welcome, ${userName }, your password is ${password }!
	<br>
	<h3>This item has been inserted into the table !</h3>
</body>
</html>

用到的jar包包括spring3中的dist目錄下的所有jar包,validation-api,hibernate-validator,slf4j-api,slf4j-log4j,log4j,commons-logging,tomcat-dbcp,mysql-connector-java-5.1.12-bin包。

運行截圖如下:

運行project後的界面:

點擊page中的鏈接後如圖所示:


當UserName和Password爲空時提示錯誤信息:


輸入符合要求的UserName和Password跳轉到下一個頁面:

現在查詢數據庫可以看到一條記錄:

該Spring MVC JUnit測試實例請點擊(Spring MVC JUnit Test測試實例 附:讀取WEB-INF下配置文件的方法

#

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章