首页 > PHP资讯 > HTML5培训技术 > Struts整合ExtJS以及遇到的一些问题(ModelDriven)

Struts整合ExtJS以及遇到的一些问题(ModelDriven)

HTML5培训技术

1准备工作:

除了平时引入的struts2的jar包以外,还需要引入struts2-json-plugin-2.1.8.1.jar;json-lib-2.1.jar这两个包。

2.建立我们的model:User

packageedu.tstc.model;

 

public classUser {

private int id;

private String username;

private String password;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

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;

}

}

 

 

3.建立我们的Action

这里是简单的演示struts-2与extjs的集成,所以全部的业务逻辑都放在Action中进行处理了。建立我们的LoginAction.当表单提交过来的时候我们也就能够在LoginAction中拿到数据了。

packageedu.tstc.action;

 

import edu.tstc.model.User;

importcom.opensymphony.xwork2.ActionSupport;

 

public classLoginAction extends ActionSupport{

private boolean success;

private String message;

private User user;

public String execute()throws Exception{

if(user.getUsername().equals(admin)&&user.getPassword().equals(admin)){

this.success = true;

this.message = 你的账号是:+user.getUsername()+密码为:+user.getPassword();

}else{

this.success = false;

this.message = 对不起,未经授权的用户不能登录该系统!;

}

return SUCCESS;

}

 

public boolean isSuccess() {

return success;

}

 

public void setSuccess(boolean success) {

this.success = success;

}

 

public String getMessage() {

return message;

}

 

public void setMessage(String message) {

this.message = message;

}

 

public User getUser() {

return user;

}

 

public void setUser(User user) {

this.user = user;

}

}

Action类中必须指定一个boolean类型的变量success,以及一个可选的String类型的变量msg,前者用于向ExtJS反馈整个的处理结果是否成功,而后者则是用于向用户提示信息。定义好这两个变量后还需要生成setter和getter方法。整个Action类正常反馈SUCCESS即可。

 

4.配置我们的struts.xml,注意extends=”json-default”

 

 

-//Apache Software Foundation//DTD StrutsConfiguration 2.0//EN

http://struts.apache.org/dtds/struts-2.0.dtd>

 

(登陆的界面),login.js(javascript代码),index.jsp(登陆成功后返回的界面)

Login.html

 

 

 

 

 

<script type=text/javascriptsrc=ext/adapter/ext/ext-base.js>《script》

<script type=text/javascriptsrc=ext/ext-all-debug.js>《script》

<script type=text/javascriptsrc=js/login.js>《script》

 

 

 

 

 

 

 

Login.js

Ext.onReady(function(){

//使用表单提示

Ext.QuickTips.init();

Ext.form.Field.prototype.msgTarget =side;

//定义一个输入表单

var simple = new Ext.FormPanel({

labelWidth:40,

baseCls:'x-plain',

defaults:{width:180},

items:[{

xtype:'textfield',

fieldLabel:'账号',

name:'user.username',

allowBlank:false,

blankText:'账号不能为空'

},{

xtype:'textfield',

inputType:password,

fieldLabel:密码,

name:'user.password',

allowBlank:false,

blankText:密码不能为空

}],

buttons:[{

text:提交,

type:submit,

handler:function(){

if(simple.form.isValid()){

Ext.MessageBox.show({

title:请等待,

msg:正在加载,

progressText:,

width:300,

progress:true,

closable:false,

animEl:'loding'

});

var f = function(v){

return function(){

var i = v/11;

Ext.MessageBox.updateProgress(i,'');

}

}

for(var i = 1; i < 13; i++){

setTimeout(f(i),i * 150);

}

//提交到服务器操作

simple.form.doAction(submit,{

url:Login.action,

method:post,

success:function(form,action){

document.location = 'index.jsp';

Ext.Msg.alert(登录成功!,action.result.message);

},

failure:function(form, action){

Ext.Msg.alert('登录失败',action.result.message);

}

});

}

}

},{

text:重置,

handler:function(){

//重置表单

simple.form.reset();

}

}]

});

//定义窗体

var _window = new Ext.Window({

title:登录窗口,

layout:fit,

width:280,

height:150,

plain:true,

bodyStyle:padding:10px,

maximizable:false,

closeAction:close,

closable:false,

collapsible:true,

plain:true,

buttonAlign:center,

items:simple

});

_window.show();

});

 

Index.jsp

<%@ page language=java contentType=text/html;charset=GB18030

pageEncoding=GB18030%>

 

 

 

 

 

 

 

恭喜你登陆成功了!

 

 

 

 

关于调试:

为了确定编写的Action是否向页面正确的返回了JSON数据,我们在调试时可以尝试直接访问Action的方式,来查看返回的JSON数据是否正确;

 

 

可能遇到的错误:

使用struts时,前台向后台传值有三种方式:

1:在Action中定义与前台页面输入变量一样变量名的变量,如:

public class UserAction {

private int id;

private String username;

private String password;

private int age;

private String address;

 

public String add(){

 

User user = new User();

user.setId(id);

user.setUsername(username);

user.setPassword(password);

user.setAge(age);

user.setAddress(address);

 

new UserManager().addUser(user);

 

return success;

}

 

public int getId() {

return id;

}

public void setId(int id){

this.id =id;

}

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 int getAge() {

return age;

}

public void setAge(int age){

this.age =age;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address =address;

}

}

这种方式的缺点是,如果需要输入的属性非常多,那么Action将变得非常臃肿,

 

2:将一个包含多个属性的对象定义到Action中去,在前台页面中通过属性来给对象赋值(如user);

Action:

public class UserAction {

 

private User user;

 

public String add(){

 

new UserManager().addUser(user);

 

return success;

}

 

public User getUser() {

return user;

}

 

public void setUser(User user) {

this.user =user;

}

}

前台输入页面:

 

 

username:

password:

age:

address:

 


 

这种做法的小缺点是前台输入页面表单域的命名变长。

 

3:第三种做法是利用ModelDriven机制,让UserAction实现一个ModelDriven接口,同时实现接口中的方法:getModel()。如下所示:

后台Action:

public class UserAction implements ModelDriven{

 

private User user;

 

@Override

public Object getModel() {

if(user == null){

user = new User();

}

return user;

}

 

public String add(){

 

new UserManager().addUser(user);

 

return success;

}

 

public User getUser() {

return user;

}

 

public void setUser(User user) {

this.user = user;

}

}

前台页面:

 

 

username:

password:

age:

 


 

这种做法的好处是后台代码量少,无多余属性定义,前台表单域的命名也很短。

 

但是,这里有一个但是。

在struts和ExtJS集成的过程中,如果你的Action类实现了这个接口,而且你还在你的Action类中定义了boolean类型的success变量和String类型的msg,

但是这两个属性你的实体类(如User类)中是没有的,因此,当Action对如登录这样的请求处理结束后,返回给请求的发出页面的JSON字段就会不包含在Action中定义的success变量和msg变量。

原因是你实现ModelDriven接口时,也实现了getModel()方法,给方法返回一个对象,比如user对象,这样前台提交过来的参数,只要名字和user对象中setter方法的名字对应就会自动映射,并且会通过user对象中定义的各个getter方法将这些属性值压入valueStack栈中,前台可以通过来获得。

换句话说实现了这个接口一个就只会把user对象中有的属性压入栈中,而在Action中定义的变量是不会压入栈中,也就是不会返回给请求的发起者,这样的话前台ExtJS页面就不会得到包括success(不可缺少)和msg(可有可无,用于存储提示信息)的JSON数据,回调时也就不会执行success所对应的方法,而是不断指定failure所对应的方法。

 

总结一下:

1:前台定义的表单域如果名字与User对象里的变量名相同便能够完成前台到后台的正常赋值;

2:Action处理结束后返回给页面的所有属性就User对象里的属性,即User对象里有什么属性就返回给页面什么属性,在Action中定义的变量不会返 回给页面;

3:假如在Action中定义一个与前台表单域名字相同的变量,该变量不会被赋值,因为只会给getModel()方法返回的对象里的属性赋值;

 

 

因此选择去掉ModelDriven的实现,或者选择在User对象中加入success变量都可以完成Struts与ExtJS的集成,使得能够正常执行success所对应的函数。但是后一种方法在User对象中加入了success变量又破坏了User对象。

 

 

 

 

 

 

 

HTML5培训技术

本文由欣才IT学院整理发布,未经许可,禁止转载。
支持11不支持0