Spring MVC常見bug總結----持續更新中
一、
Spring MVC的配置檔案Springmvc-servlet.xml報錯,在新增
<context:component-scan base-package="controller" />
來指定控制器所在的包時,視窗顯示紅叉,報錯內容為:
Multiple annotations found at this line:
- schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/
springcontext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root
element of the document is not <xsd:schema>.
- cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element
'context:component-scan'.
經過檢查,發現時springmvc-servlet的頭中,關於名稱空間(是不是這麼說的。。。)的定義有誤,導致找不到我對應的檔案。
之前,我的頭定義如下:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/springcontext.xsd">
xsd等沒有指定正確的檔案版本,根據自己的jar包版本做修改如下:
<beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
二、依然是坑爹的配置bug
我在實驗一個簡單的Spring MVC的demo的時候,所有的程式碼和jar、環境均已經搞定,但是run as server之後,出現:
org.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 75; cvc-elt.1: 找不到元素 'beans' 的宣告
這樣的報錯。
在實驗切xmlns中的檔案版本等等方法之後,依然沒有效果。但是奇怪的是,我之前一個類似的專案,該配置檔案極其類似,只是從傳統控制器風格變成了使用註解控制器,程式並沒有報錯!
後修改,在beans元素前面加上一個名稱空間beans,然後就不報錯了。
前後對比圖如下:
1.發生錯誤的時候:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<mvc:annotation-driven/>
<!-- ①:對web包中的所有類進行掃描,以完成Bean建立和自動依賴注入的功能 -->
<context:component-scan base-package="controller" />
<mvc:resources mapping="/*.html" location="/"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
2.新增beans名稱空間之後:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
<mvc:annotation-driven />
<!-- ①:對web包中的所有類進行掃描,以完成Bean建立和自動依賴注入的功能 -->
<context:component-scan base-package="net.use" />
<!-- 這兩個類用來啟動基於Spring MVC的註解功能,將控制器與方法對映加入到容器中 -->
<beans:bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<beans:bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- 這個類用於Spring MVC檢視解析 -->
<beans:bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/pages/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
</beans:beans>
不報錯了。。。
坑爹。。。
到現在還不知道是什麼原因。
3.今天準備嘗試一下實現依賴注入,途中發生了一個有趣的bug。
嚴重: Servlet.service() for servlet [s nested exception is org.springframewo
具體的描述沒了
主要是怎麼回事呢。
說表單資料提交後自動繫結到User類的時候發生了一個錯誤,無法從String物件轉換成自己定義的Connection物件。
恍然想起來,form提交到伺服器的全部是String,但是我們自己定義的類的屬性可能是double,可能是一個物件。
所以為了解決這個問題,參考了之前看到的某篇文章,在轉成User類之前,先換成一個所有屬性都用String表示,屬性值和User類一一對應的UserForm類。如下:
package net.use.info;
import java.io.Serializable;
import net.use.connection.Connection;
public class User implements Serializable {
/**
* @author zjn
*/
private static final long serialVersionUID = 1L;
private String name; // name
private String pwd; // pwd
private Integer age; // age
private String sex;
private Connection connection;//connection是介面
//全部實現了set和get方法�? 以此完成依賴注入(設值注入)
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex=sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Connection getConnection() {
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
}
然後是userForm類
package net.use.form;
public class UserForm {
private String name; // name
private String pwd; // pwd
private Integer age; // age
private String sex;
private String connection;//connection是介面
private String connection_type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getConnection() {
return connection;
}
public void setConnection(String connection) {
this.connection = connection;
}
public String getConnection_type() {
return connection_type;
}
public void setConnection_type(String connection_type) {
this.connection_type = connection_type;
}
}
這樣,在Controller中,就可以先把Form資料換成UserForm物件,然後再一個一個把屬性值賦給User物件。如下:
@RequestMapping("register")
public String Save(@ModelAttribute("form") UserForm userForm, Model model) { // user:檢視層傳給控制層的表單物件;model:控制層返回給檢視層的對�?
//model.addAttribute("user", user);
//System.out.println(user.getName()+","+user.getSex()+","+user.getPwd()+","+user.getAge());
//first,to convert the userform to the user
User user = new User();
user.setName(userForm.getName());
user.setAge(userForm.getAge());
user.setSex(userForm.getSex());
user.setPwd(userForm.getPwd());
Connection con;
if(userForm.getConnection_type().equals("phone")) {
con = new Phone();
con.setNumber(userForm.getConnection());
user.setConnection(con);
}else if(userForm.getConnection_type().equals("msn")) {
con = new MSN();
con.setNumber(userForm.getConnection());
user.setConnection(con);
}
怪不得之前看的那篇文章要用什麼Form類,原來是這個鬼。。。。get!