錯(cuò)誤信息:出現(xiàn)java.lang.NoSuchMethodException setUser([LJava.lang.String;)異常
struts2中的UserAction:
這個(gè)是開(kāi)始的struts.xml中的代碼:
$(function(){
var json = {"user":{"username":"zhangsan","password":"123"}};//方法1
//json = {"name":"zhanglong"};// 方法2
//json = {"user.username":"zhangsan","user.password":123};//方法3
});
用方法1會(huì)出項(xiàng)上述錯(cuò)誤,方法2和方法3都可行。
原因:
方法2成功的原因是{"name":"zhanglong"}傳遞的是一個(gè)名值對(duì),就像是request的parameter.
方法3成功也是一樣的,struts2的OGNL會(huì)識(shí)別user.username,并把它對(duì)應(yīng)的值"zhangsan"存放到user的username屬性上
方法1失敗是因?yàn)閭鞯拿祵?duì)是:"user":"{'username':'zhangsan','password','123'}",這樣struts就會(huì)你要將"{'username':'zhangsan','password','123'}"這個(gè)字符串賦值給user對(duì)象,它就會(huì)調(diào)用setUser(String user)方法(或者是setUser(String[] user)),由于UserAction中沒(méi)有這個(gè)方法,所以會(huì)報(bào)錯(cuò)。
解決方法:
根據(jù)jsonplugin官方的文檔,頁(yè)面?zhèn)魅氲恼?qǐng)求的content-type要是application/json,否則json的interceptor不會(huì)幫你將json轉(zhuǎn)換為java對(duì)象,這里他忘了說(shuō)明一點(diǎn),jsonplugin中只是定義了json的interceptor,并沒(méi)有將其放入到package的攔截器棧中,還需要我們自己放入自己的package中。如下:
只有這樣做了后,json攔截器才會(huì)幫你做轉(zhuǎn)換。
還有,如果UserAction中有個(gè)userService的話,需要設(shè)置action的result的param:
如果user對(duì)象是從hibernate獲取的,可能得到的是一個(gè)代理對(duì)象,對(duì)其進(jìn)行json序列化時(shí)會(huì)出錯(cuò)。解決辦法是為User對(duì)象加上@Proxy(lazy=false)注解。
struts2中的UserAction:
1 public class UserAction{
2 private User user;
3 private String name;
4 public void setName(String name){
5 this.name = name;
6 }
7 public String getName(){
8 return name;
9 }
10 public User getUser() {
11 return user;
12 }
13
14
15 public void setUser(User user) {
16 this.user = user;
17 }
18
19 public String execute(){
20 System.println(user.getUsername);
21 }
22
23 }
24
User就兩個(gè)屬性:username/password.2 private User user;
3 private String name;
4 public void setName(String name){
5 this.name = name;
6 }
7 public String getName(){
8 return name;
9 }
10 public User getUser() {
11 return user;
12 }
13
14
15 public void setUser(User user) {
16 this.user = user;
17 }
18
19 public String execute(){
20 System.println(user.getUsername);
21 }
22
23 }
24
這個(gè)是開(kāi)始的struts.xml中的代碼:
<package name="json" extends="json-default">
<action name="save" class="com.aaron.example.action.UserAction">
<result type="json"></result>
</action>
</package>
這個(gè)是jQuery代碼:
<action name="save" class="com.aaron.example.action.UserAction">
<result type="json"></result>
</action>
</package>





原因:
方法2成功的原因是{"name":"zhanglong"}傳遞的是一個(gè)名值對(duì),就像是request的parameter.
方法3成功也是一樣的,struts2的OGNL會(huì)識(shí)別user.username,并把它對(duì)應(yīng)的值"zhangsan"存放到user的username屬性上
方法1失敗是因?yàn)閭鞯拿祵?duì)是:"user":"{'username':'zhangsan','password','123'}",這樣struts就會(huì)你要將"{'username':'zhangsan','password','123'}"這個(gè)字符串賦值給user對(duì)象,它就會(huì)調(diào)用setUser(String user)方法(或者是setUser(String[] user)),由于UserAction中沒(méi)有這個(gè)方法,所以會(huì)報(bào)錯(cuò)。
解決方法:
根據(jù)jsonplugin官方的文檔,頁(yè)面?zhèn)魅氲恼?qǐng)求的content-type要是application/json,否則json的interceptor不會(huì)幫你將json轉(zhuǎn)換為java對(duì)象,這里他忘了說(shuō)明一點(diǎn),jsonplugin中只是定義了json的interceptor,并沒(méi)有將其放入到package的攔截器棧中,還需要我們自己放入自己的package中。如下:
1 <interceptors>
2 <interceptor-stack name="myDefaultStack">
3 <interceptor-ref name="json"/>
4 <interceptor-ref name="defaultStack"/>
5 </interceptor-stack>
6 </interceptors>
7
8 <default-interceptor-ref name="myDefaultStack"/>
還要設(shè)置jquery的ajax請(qǐng)求的content-type和傳遞類(lèi)型為"POST":2 <interceptor-stack name="myDefaultStack">
3 <interceptor-ref name="json"/>
4 <interceptor-ref name="defaultStack"/>
5 </interceptor-stack>
6 </interceptors>
7
8 <default-interceptor-ref name="myDefaultStack"/>
1 $.ajax({
2 type:"POST",
3 data:jsonText,
4 url:"save.action?number=" + Math.random(),
5 contentType:"application/json"
6 });
其中jsonText如下:
2 type:"POST",
3 data:jsonText,
4 url:"save.action?number=" + Math.random(),
5 contentType:"application/json"
6 });
1 var jsonText = "{'user':{
2 'username':'zhangsan',
3 'password':'123'
4 }
5 }"
注意,整個(gè)jsonText是個(gè)字符串,其中的名值對(duì)的名要用''包起來(lái),否則會(huì)報(bào)異常,指出json格式不對(duì)。2 'username':'zhangsan',
3 'password':'123'
4 }
5 }"
只有這樣做了后,json攔截器才會(huì)幫你做轉(zhuǎn)換。
還有,如果UserAction中有個(gè)userService的話,需要設(shè)置action的result的param:
1 <result type="json">
2 <param name="excludeProperties">
3 userService
4 </param>
5 </result>
這樣就不會(huì)將userService進(jìn)行序列化了,或者可以將action中的getUserService()方法去掉。2 <param name="excludeProperties">
3 userService
4 </param>
5 </result>
如果user對(duì)象是從hibernate獲取的,可能得到的是一個(gè)代理對(duì)象,對(duì)其進(jìn)行json序列化時(shí)會(huì)出錯(cuò)。解決辦法是為User對(duì)象加上@Proxy(lazy=false)注解。