Day7 - Struts2 - jQuery

1. Struts2 与 Servlet

  • 封装 Servlet 的大部分功能,Struts2 是 Servlet 的上层
  • Struts2 能做的 Servlet 都能做,反之不行
  • Struts2 框架提供了 action,服务器资源增添了 action
  • Struts2 在 web.xml 中配置过滤器管理 action

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <filter>
        <filter-name>struts2</filter-name>
        <!--struts2框架提供的核心类过滤器,拿到参数,封装对象-->
        <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>-->

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <!--通过 .action -->
        <url-pattern>*.action</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <!--通过 .jsp -->
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>

</web-app>
public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter {}
  • struts2 框架核心类 StrutsPrepareAndExecuteFilter 实现 Servlet 提供的 Filter 接口
  • web.xml 中 <filter-mapping> 目前只允许通过 .action.jsp 后缀的链接

jar 包 链接:http://pan.baidu.com/s/1nvkLAR3 密码:vze1

2. 拦截器

  • 拦截访问 action 的请求
  • 给这个 action 加入新的丰富功能(上传、参数自动接收、类型自动转换等等)
  • 拦截之后,在 intercept 函数 调用 invoke 方法 才真正启动 action

MyInterceptor.java

package com.shuai.web.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

/**
 * Created by shuai
 * on 2017/8/21.
 */
public class MyInterceptor implements Interceptor {

    @Override
    public void destroy() {
        System.out.println("MyInterceptor destroy...");
    }

    @Override
    public void init() {
        System.out.println("MyInterceptor init...");
    }

    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        System.out.println("before...");
        String s = actionInvocation.invoke(); // 真正调用action方法 显示toIndex方法中的打印
        System.out.println("after...");
        return s;
    }
}

struts.xml 路径固定,放在 src 下

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

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <package name="cms-package" extends="struts-default">
        <interceptors>
            <interceptor name="auth" class="com.shuai.web.interceptor.MyInterceptor"></interceptor>
            <!--拦截器栈-->
            <interceptor-stack name="cmsAuthStack">
                <interceptor-ref name="auth"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <global-results>
            <result name="toLogin">
                /WEB-INF/jsp/login.jsp
            </result>
        </global-results>
    </package>
</struts>

IndexAction.java 在 @Action 注解中加上拦截器

package com.shuai.web.action;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;

// 继承 ActionSupport
public class IndexAction extends ActionSupport {
    @Action(value = "/toIndex",
            results = {@Result(location = "/index.jsp")}, // 默认的SUCCESS,不用指明name
            // 配置拦截器,可以拦下页面,做一些处理再显示
            interceptorRefs = {@InterceptorRef("cmsAuthStack")}
    )
    public String toIndex() {
        System.out.println("in index...");
        return SUCCESS; // Action 接口中 String SUCCESS = "success";
    }
}

3. 前端浏览器与后端数据库的交互过程 - 分层开发

Browser:前端页面点击超链接,跳转到 Action 链接;

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>主页</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">

    <script src="frameworks/jquery-2.1.4/jquery.min.js"></script>
    <script src="js/index.js"></script>
</head>
<body style="margin-left: 10px">

<h1>Ah! We are here</h1>

<ul>
    <li><a class="ff" href="javascript:void(0);">显示用户信息</a></li>
    <li><a class="ff" href="javascript:void(0);">添加用户信息</a></li>
</ul>

<div class="below"></div>

</body>
</html>

通过 jQuery 的 load 方法实现在 index.jsp 页面中异步加载其他 jsp 页面

index.js

$(function () {

    // class选择器
    $(".ff").click(function () {
        console.log("in ff...");
        switch ($(this).text()) {
            case "显示用户信息":
                // 异步请求 Ajax
                // load 方法内部方式实现了 Ajax 在同一个页面的 div 中加载另一个页面
                // 选中 below 这个 div 显示 toShowUser.action 对应页面的内容
                $(".below").load("toShowUser.action?parentDir=jsp&specifyUrl=showUser.jsp");
                break;
            case "添加用户信息":
                // 同上
                $(".below").load("toAddUser.action?parentDir=jsp&specifyUrl=addUser.jsp");
                break;
            default:
                break;
        }
    });

});
Action:每个 Action 对应 UserAction 类中的一个函数,比如 toShowUser(),函数内调用 service 接口实现特定功能,比如 service.findAllUsers()

UserAction 类中的 toShowUser 函数

@Action(value = "/toShowUser", results = {
        @Result(location = "/WEB-INF/jsp/showUser.jsp"),
        @Result(name = ERROR, location = "/index.jsp", type = "redirectAction")
})
public String toShowUser() throws ServiceException {

    System.out.println("show user...");

    List<User> list = service.findAllUsers(); // service 接口
    requestMap.put("list", list); // 通过UserAction类实现RequestAware接口传值

    return SUCCESS; // Action 接口 String SUCCESS = "success";
}
  • @Action 注解中 @Result 默认的是 SUCCESS,不用指明,但是 ERROR 要指明
  • SUCCESS = String "success"
Service:与 Service 接口同时存在一个 Service 实现类 UserServiceImpl,该实现类调用 UserDao 的方法完成与数据库的交互;

UserServiceImpl 类实现 service 接口方法

package com.shuai.service;

import com.shuai.bean.User;
import com.shuai.common.ServiceException;
import com.shuai.dao.UserDao;

import java.util.List;

// UserService 的实现类
public class UserServiceImpl implements UserService {

    private UserDao dao = new UserDao();

    @Override
    public void registerUser(User user) throws ServiceException {
        User u = dao.findUserByName(user.getName()); // 查找用户 调用 UserDao 方法
        if (u != null) {
            throw new ServiceException("user exist!");
        } else {
            dao.saveUser(user); // 存入数据库 调用 UserDao 方法
        }
    }

    @Override
    public List<User> findAllUsers() throws ServiceException {
        return dao.findAllUsers(); // 查找所有用户 调用 UserDao 方法
    }
}
dao:定义了与数据库交互的方法,通过 Hibernate 实现;

UserDao 类

package com.shuai.dao;

import com.shuai.bean.User;
import com.shuai.common.HibernateSessionFactory;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import java.util.List;

/**
 * Created by shuai
 * on 2017/8/21.
 */
public class UserDao {

    // 保存用户
    public void saveUser(User user) {
        Session session = HibernateSessionFactory.getSession();
        Transaction ts = session.beginTransaction();
        session.save(user); // 事物内容
        ts.commit();
    }


    // 查询用户
    public User findUserByName(String name) {

        Session session = HibernateSessionFactory.getSession();
        Criteria criteria = session.createCriteria(User.class);

        List<User> list = criteria.add(Restrictions.eq("name", name)).list();

        if (list.size() == 0) {
            return null;
        } else {
            return list.get(0);
        }
    }

    // 查询所有用户
    public List<User> findAllUsers() {
        Session session = HibernateSessionFactory.getSession();
        SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM TBL_USER");
        sqlQuery.addEntity(User.class); // hibernate.cfg文件注册了映射类
        return sqlQuery.list();
    }
}
db:通过 hibernate.cfg.xml 文件配置好,就可以前后端交互了。
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>
        <property name="connection.username">briup</property>
        <property name="connection.password">briup</property>
        <property name="connection.url">
            jdbc:oracle:thin:@172.20.10.2:1521:XE
        </property>
        <property name="connection.driver_class">
            oracle.jdbc.driver.OracleDriver
        </property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!--数据库方言-->
        <property name="dialect">
            org.hibernate.dialect.OracleDialect
        </property>

        <!--映射类-->
        <mapping class="com.shuai.bean.User"/>

    </session-factory>
</hibernate-configuration>
项目目录

4. 添加用户信息到数据库

addUser.jsp

可以用 form 表单

<h1>addUser</h1>

<form action="toSaveUser.action" method="post">
    用户:<input type="text" name="user.name"><br>
    密码:<input type="password" name="user.password"><br>
    <input type="submit" value="提交">
</form>

也可以用超链接

<h1>addUser</h1>

用户: <input class="na" type="text" name="user.name"><br>
密码: <input class="pwd" type="password" name="user.password"><br><br>
<a id="sb" class="btn btn-success" href="javascript:void(0);"
   style="width: 80px; margin-left: 70px">提交</a>
addUser

提交按钮对应的 href 是 index.js 中的跳转到 toSaveUser.action 操作

$(function () {
    // id选择器
    $("#sb").click(function () {
        console.log("in sb...");
        console.log($(".na").val() + " " + $(".pwd").val());

        // js对象
        var user = {};
        user['user.name'] = $(".na").val();
        user['user.password'] = $(".pwd").val();
        console.log(user);
        
        // 传给 toSaveUser.action 页面在前端输入的 User
        $.post("toSaveUser.action", user, function () {
            console.log("发送成功");
        })
    });
});

UserAction 类中的 toSaveUser 函数对应 toSaveUser.action

//保存用户
@Action(value = "/toSaveUser", results = {
        @Result(location = "/index.jsp"),
        @Result(name = ERROR, location = "/WEB-INF/jsp/addUser.jsp")
})
public String toSaveUser() {
    System.out.println("save user...");
    System.out.println("username: " + user.getName());
    System.out.println("password: " + user.getPassword());

    // $.post("toSaveUser.action", user,..) 接收 user
    try {
        service.registerUser(user); // 存入数据库
        System.out.println("用户存入数据库...");
        return SUCCESS;
    } catch (ServiceException e) {
        e.printStackTrace();
        return ERROR;
    }
}

toSaveUser 函数调用 Service 接口的 registerUser 方法

UserServiceImpl (Service 的实现类)

package com.shuai.service;

import com.shuai.bean.User;
import com.shuai.common.ServiceException;
import com.shuai.dao.UserDao;

import java.util.List;

// UserService 的实现类
public class UserServiceImpl implements UserService {

    private UserDao dao = new UserDao();

    @Override
    public void registerUser(User user) throws ServiceException {
        User u = dao.findUserByName(user.getName());
        if (u != null) {
            throw new ServiceException("user exist!");
        } else {
            dao.saveUser(user); // 存入数据库
        }
    }

    @Override
    public List<User> findAllUsers() throws ServiceException {
        return dao.findAllUsers();
    }
}

registerUser 函数调用 UserDao 的 findUserByName 和 saveUser 方法

package com.shuai.dao;

import com.shuai.bean.User;
import com.shuai.common.HibernateSessionFactory;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import java.util.List;

/**
 * Created by shuai
 * on 2017/8/21.
 */
public class UserDao {

    // 保存用户
    public void saveUser(User user) {
        Session session = HibernateSessionFactory.getSession();
        Transaction ts = session.beginTransaction();
        session.save(user); // 事物内容
        ts.commit();
    }

    // 查询用户
    public User findUserByName(String name) {

        Session session = HibernateSessionFactory.getSession();
        Criteria criteria = session.createCriteria(User.class);

        List<User> list = criteria.add(Restrictions.eq("name", name)).list();

        if (list.size() == 0) {
            return null;
        } else {
            return list.get(0); // 如果找到了,第一个元素就是
        }
    }
}

这样就可以把前端 addUser.jsp 中输入的 User 存入数据库。

5. 显示用户信息

操作顺序 和 添加用户信息 一样

index.jsp 主页面点进超链接进入 toShowUser.action

UserAction 类中 toShowUser.action

@Action(value = "/toShowUser", results = {
        @Result(location = "/WEB-INF/jsp/showUser.jsp"), // 可以这样指定location路径
        @Result(name = ERROR, location = "/index.jsp", type = "redirectAction")
})
public String toShowUser() throws ServiceException {

    System.out.println("show user...");

    List<User> list = service.findAllUsers();
    requestMap.put("list", list); // 通过UserAction类实现RequestAware接口传值

    return SUCCESS;
}

UserServiceImpl (Service实现类)的 findAllUsers 方法

@Override
public List<User> findAllUsers() throws ServiceException {
    return dao.findAllUsers();
}

UserDao 类的 findAllUsers 方法

// 查询所有用户
public List<User> findAllUsers() {
    Session session = HibernateSessionFactory.getSession();
    SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM TBL_USER");
    sqlQuery.addEntity(User.class); // hibernate.cfg文件注册了映射类
    return sqlQuery.list();
}

执行数据库查询,返回 list

showUser.jsp 显示表内容

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>showUser</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<h1>showUser</h1>

<table class="table table-striped table-bordered" style="width: 50%">
    <thead>
    <tr>
        <th>username</th>
        <th>password</th>
    </tr>
    </thead>

    <tbody>
    <%--显示传入的list--%>
    <c:forEach items="${list}" var="v">
        <tr>
            <td> ${v.name}</td>
            <td> ${v.password}</td>
        </tr>
    </c:forEach>
    </tbody>
</table>

</body>
</html>
showUser
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,100评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,862评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,993评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,309评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,303评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,421评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,830评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,501评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,689评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,506评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,564评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,286评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,826评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,875评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,114评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,705评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,269评论 2 341

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,550评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 3,784评论 0 11
  • 概述 什么是Struts2的框架Struts2是Struts1的下一代产品,是在 struts1和WebWork的...
    inke阅读 2,236评论 0 50
  • (一)Struts、Spring、Hibernate、Mybatis框技术 1.Struts2.0有几种标签库 【...
    独云阅读 3,218评论 0 62
  • 丫头难得从上海回来休息两天,我和货货就逮着机会,填鸭式的让她吃遍家中的美食。这不女儿昨晚10.50到站,货货从晚饭...
    山青青阅读 1,490评论 27 28