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

  • 相关阅读:
    IDEA连接Spark集群执行Scala程序
    win10安装mysql,及重装
    python生产和消费kafka数据
    protobuf 协议浅析
    操作系统-第十三章-I/O系统
    操作系统-第十二章-大容量存储结构
    操作系统-第十一章-文件系统的实现
    JSONP跨域提交请求
    标识多个物体并返回物体中心坐标方法的实现
    SkyWalking Agent端日志插件的编写历程与使用说明
  • 原文地址:https://www.cnblogs.com/wanggangblog/p/3471944.html
Copyright © 2011-2022 走看看