zoukankan      html  css  js  c++  java
  • Struts整合ExtJS

    1准备工作:

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

    2.建立我们的model:User

    package edu.tstc.model;

    public class User {

    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中拿到数据了。

    package edu.tstc.action;

    import edu.tstc.model.User;

    import com.opensymphony.xwork2.ActionSupport;

    public class LoginAction 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”

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

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

    <struts>

    <constant name="struts.i18n.encoding" value="UTF-8"/>

    <package name="extjs" extends="json-default" namespace="/">

    <action name="Login" class="edu.tstc.action.LoginAction">

    <result type="json"></result>

    </action>

    </package>

    </struts>

    result的type必须指定为json。一旦为某个Action指定了一个类型为json的Result,则该Result无须映射到任何视图资源,因为JSON插件会负责将Action里的信息序列化成JSON格式的字符串,并将该字符串返回给发出异步请求的浏览器页面。

    简单的说JSON插件允许我们在客户端页面的JavaScript中一步调用Action,而且Action不再需要使用视图资源去显示该Action里的状态信息,而是由JSON插件负责将Action里的状态信息返回给调用页面——通过这种方式,就可以完成Ajax交互。

    同时还有两个需要注意的地方:

    1:在配置struts.i18n.encoding常量时需要指定为UTF-8编码,这是因为Ajax的POST请求都是以UTF-8的方式进行编码的;

    2:在配置包时,需要继承json-default,而不是原来的struts-default包,这是因为只有该包下才有json类型的Result。

    一旦我们将某个逻辑配置成为json类型,这就意味着该逻辑视图无需指定物理视图资源,因为json插件会将该Action序列化后发送给客户端。

    5.在web.xml文件中配置struts2

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app version="2.5"

    xmlns="http://java.sun.com/xml/ns/javaee"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <filter>

    <filter-name>struts2</filter-name>

    <filter-class>

    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

    </filter-class>

    </filter>

    <filter-mapping>

    <filter-name>struts2</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

    <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

    </web-app>

    6.接下来是前台的页面,其中包括login.html(登陆的界面),login.js(javascript代码),index.jsp(登陆成功后返回的界面)

    Login.html

    <!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=GB18030">

    <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"/>

    <script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>

    <script type="text/javascript" src="ext/ext-all-debug.js"></script>

    <script type="text/javascript" src="js/login.js"></script>

    <title>Extjs 学习</title>

    </head>

    <body>

    </body>

    </html>

    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:{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:"",

    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",

    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"%>

    <!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=GB18030">

    <title>Insert title here</title>

    </head>

    <body>

    恭喜你登陆成功了!

    </body>

    </html>

    关于调试:

    为了确定编写的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;

        }

    }

    前台输入页面:

    <form action="test/user.action" method="post">

    <input type="hidden" name="method:add">

            username:<input type="text" name="user.username"> <br/>

            password:<input type="text" name="user.password"> <br/>

            age:<input type="text" name="user.age"> <br/>

            address:<input type="text" name="user.address"> <br/>

    <input type="submit" name="submit" value="添加用户">

    </form> <br/>

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

    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;

        }

    }

    前台页面:

    <form action="test/user.action" method="post">

    <input type="hidden" name="method:add">

            username:<input type="text" name="username"> <br/>

            password:<input type="text" name="password"> <br/>

            age:<input type="text" name="age"> <br/>

    <input type="submit" name="submit" value="添加用户">

    </form> <br/>

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

    但是,这里有一个但是。

    在struts和ExtJS集成的过程中,如果你的Action类实现了这个接口,而且你还在你的Action类中定义了boolean类型的success变量和String类型的msg,但是这两个属性你的实体类(如User类)中是没有的,因此,当Action对如登录这样的请求处理结束后,返回给请求的发出页面的JSON字段就会不包含在Action中定义的success变量和msg变量。原因是你实现ModelDriven接口时,也实现了getModel()方法,给方法返回一个对象,比如user对象,这样前台提交过来的参数,只要名字和user对象中setter方法的名字对应就会自动映射,并且会通过user对象中定义的各个getter方法将这些属性值压入valueStack栈中,前台可以通过<s:property value="…."/>来获得。换句话说实现了这个接口一个就只会把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对象。

    正文引用:

    http://blog.csdn.net/li_tengfei/article/details/6098145

    http://wenku.baidu.com/view/6da1c5bb84868762cbaed509.html

  • 相关阅读:
    jQuery 语法
    jQuery 简介
    把数据存储到 XML 文件
    XML 注意事项
    XML DOM (Document Object Model) 定义了访问和操作 XML 文档的标准方法。
    通过 PHP 生成 XML
    XML 命名空间(XML Namespaces)
    XML to HTML
    XMLHttpRequest 对象
    使用 XSLT 显示 XML
  • 原文地址:https://www.cnblogs.com/wanggangblog/p/3471944.html
Copyright © 2011-2022 走看看