使用struts2框架来实现前台与后台的交互

由于这几天到处出差,比较忙,博客的更新速度比较慢。今天的这个是小实例的功能和上一篇博文中的功能是一致的,只是将原来由servlet实现的部分功能用前一段时间比较流行的struts2框架来实现,而现在比较流行的是Spring MVC,这个在以后也会专门来写一篇博文。


还是惯例,贴一张项目截图:
这里写图片描述


这次要使用struts2来完成前台到后台的映射,所以要先搭建struts2的环境。
首先要导入struts2依赖的jar包,这里还是和以前一样,使用手动导入的方式,所以要先下载到需要的jar,这些jar包可以去struts2的官网上下载。但是struts2运行必须需要的jar包如下:
这里写图片描述
将这个jar放在WEB-INF下的lib目录下,并且将该目录添加到运行环境中。

接下来要在web.xml中配置StrutsPrepareAndExecuteFilter,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>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
</web-app>

这样struts2就会拦截所有以.action结尾的请求。至此,struts2的运行环境就算配置完成了。


接下来就可以开始编写struts2的代码了,这里要说的是service层和Dao层和上一个博文中的实例一模一样,是使用原生jdbc实现数据库的相关操作,你可以看我上一篇博文,也可以在本文的末尾下载当前实例的完整项目,这里就不再说了。
编写Action只需要继承ActionSupport即可,源代码如下:

package com.leo.action;

import com.alibaba.fastjson.JSONObject;
import com.leo.service.Service;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

/**
 * company:**数码技术股份有限公司
 * Created by leo on 2016/9/26.
 */
public class UserAction extends ActionSupport{
    private HttpServletRequest request = ServletActionContext.getRequest();
    private HttpServletResponse response = ServletActionContext.getResponse();
    private Service service = new Service();
    public void query(){
        List<Map<String,Object>> userData = service.queryUserData();
        PrintWriter out = null;
        try {
            out = response.getWriter();
            JSONObject jsonObject = new JSONObject();
            out.write(jsonObject.toJSONString(userData));
            //out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String delete(){
        String employeeid = request.getParameter("employeeid");
        String result = service.deleteUserDate(employeeid);
        return result;
    }

    public String insert(){
        String firstname = request.getParameter("firstname");
        String lastname = request.getParameter("lastname");
        String email = request.getParameter("email");
        String phonenumber = request.getParameter("phonenumber");
        String hiredate = request.getParameter("hiredate");
        String salary = request.getParameter("salary");
        String result = service.insertUserDate(firstname,lastname,email,phonenumber,hiredate,salary);

        return result;
    }

    public String update(){
        String employeeid = request.getParameter("employeeid");
        String firstname = request.getParameter("firstname");
        String lastname = request.getParameter("lastname");
        String email = request.getParameter("email");
        String phonenumber = request.getParameter("phonenumber");
        String hiredate = request.getParameter("hiredate");
        String salary = request.getParameter("salary");
        String result = service.modifyUserDate(employeeid,firstname,lastname,email,phonenumber,hiredate,salary);

        return result;
    }
}

在以上的代码中,实现了对数据的增删改查操作,这和之前的servlet比起来要简洁了好多。这段代码和之前的servlet还有一个重要的不同点,就在没有在代码中执行重定向的操作,而这个操作可以直接交给struts2框架来完成。注意:在使用struts2时要正确使用void和String 的返回值类型,当需要根据程序执行状态跳转页面时要使用String的返回值类型,就像本项目中的增删改操作;当只是需要获取数据不要判断状态跳转页面时,要使用void的返回值类型,就像本项目中的查询操作。


Action编写完毕后,项目还是不能成功运行的,还需要告诉struts2要如何执行Action中的方法,这就需要配置struts2的配置文件,struts2的配置文件名称默认为struts.xml,并且需要放在编译文件的根目录下,如果在项目中没有使用默认的路径或文件名称,则需要在web.xml中配置StrutsPrepareAndExecuteFilter时再配一个init-param的节点。在本项目中使用的是默认的文件名和路径。struts.xml的配置如下:

<?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>
    <constant name="struts.devMode" value="true" />
    <package name="queryUserDate" namespace="/" extends="struts-default">
        <action name="*" class="com.leo.action.UserAction" method="{1}">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>

在struts2的配置文件中,首先要将开发模式设置成true,不认在struts.xml配制的代码不会立即生效。接着就是配制Action的访问映射,在这个映射的配制中我使用了通配符来简化配制。如果不使用通配符,增删改查每一个方法都需要单独配制。上面的配制等效以下配制:

<?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>
    <constant name="struts.devMode" value="true" />
    <package name="queryUserDate" namespace="/" extends="struts-default">
        <action name="query" class="com.leo.action.UserAction" method="query">
        </action>
        <action name="insert" class="com.leo.action.UserAction" method="insert">
            <result name="success">/index.jsp</result>
        </action>
        <action name="update" class="com.leo.action.UserAction" method="update">
            <result name="success">/index.jsp</result>
        </action>
        <action name="delete" class="com.leo.action.UserAction" method="delete">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>

灵活的使用通配符能提高代码的编写效率,在未来修改起来也比较方便。
还要说明的是这个result标签,前面提到的页面的跳转是交给struts2来完成的,这个result就是用来判断返回值的,如果action的返回值和result的name属性值一致,则跳转到result指定的页面。


到这里程序的编写全部完成了,程序的运行结果如下:
这里写图片描述
这里还发现一个很重要的问题,这也是之前的遗留下来的问题,那就是转发和重定向的区别。从截图上可以看到,地址栏在执行完插入操作后发生了变化,但是页面显示的类型却还是index.jsp的内容。这样就会导致一个问题,当我来这种情况下执行刷新操作时,程序会再一次执行插入操作,而我的本意只是想刷新当前的index.jsp页面。出现这种问题是因为result的跳转页面默认使用的是转发的方式,而要解决这个问题,就需要我们将result跳转页面的方式设置成重定向的方式。修改过后的代买如下:

<?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>
    <constant name="struts.devMode" value="true" />
    <package name="queryUserDate" namespace="/" extends="struts-default">
        <action name="*" class="com.leo.action.UserAction" method="{1}">
            <result name="success" type="redirect">/index.jsp</result>
        </action>
    </package>
</struts>

这样执行完插入操作以后的界面如下:
这里写图片描述
转发和重定向的区别:转发是将当前页面的request传给要跳转的页面,而地址栏的地址为发起跳转页面的地址;重定向是重新生成request传给要跳转的页面,地址栏的地址为跳转的页面地址。


最后还有一个必须要提一下,在web.xml中为了让拦截器只拦截我的action请求,我指定了请求后缀为.action,这样之前写的那些servlet请求就失效了,需要对原来的前台页面进行修改,将原来的servlet地址改成现在的action地址,具体源码如下:

<%--
  Created by IntelliJ IDEA.
  User: leo
  Date: 2016/9/17
  Time: 15:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
  String path = request.getContextPath();
  String context = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
  <head>
    <title>展示页面</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="-1">
    <script type="text/javascript" src="jslib/jquery-1.11.2.min.js"></script>
    <script type="text/javascript">
      var global = null;
      $(function(){
      debugger;
        $.ajax({
          url:'<%=context%>query.action',
          dataType:'json',
          success:function(data){
            global=data;
            $("#display").html("");
            $("#display").append("<tr> <th>employee_id</th> <th>first_name</th> <th>last_name</th> <th>email</th> <th>phone_number</th> <th>hire_date</th> <th>salary</th> <th>operator</th> </tr>");
            for(var i in data){
              $("#display").append("<tr> <td>"+data[i].employeeid+"</td> <td>"+data[i].firstname+"</td> <td>"+data[i].lastname+"</td> <td>"+data[i].email+"</td> <td>"+data[i].phonenumber+"</td> <td>"+data[i].hiredate+"</td> <td>"+data[i].salary+"</td> <td><a href='#' onclick='update("+i+")'>update</a>|<a href='#' onclick='add()'>add</a>|<a href='<%=context%>delete.action?employeeid="+data[i].employeeid+"'>delete</a></td> </tr>");
            }
          }
        });
      })
      function update(index) {
        alert(global[index].employeeid);
        $("#addOrUpate").html("");
        $("#addOrUpate").html('<form action="<%=context%>update.action">'
                        +'<input type="hidden" name="employeeid" value="'+global[index].employeeid+'">'
                +'first_name:<input type="text" name="firstname" value="'+global[index].firstname+'"><br>'
                +'last_name:<input type="text" name="lastname" value="'+global[index].lastname+'"><br>'
                +' email:<input type="text" name="email" value="'+global[index].email+'"><br>'
                +'   phone_number:<input type="text" name="phonenumber" value="'+global[index].phonenumber+'"><br>'
                +'hire_date:<input type="text" name="hiredate" value="'+global[index].hiredate+'"><br>'
                +'salary:<input type="text" name="salary" value="'+global[index].salary+'"><br>'
                +'<input type="submit" value="Submit">'
                +'</form>'
        );
      }
      function add() {
        $("#addOrUpate").html("");
        $("#addOrUpate").html('<form action="<%=context%>insert.action">'
                +'first_name:<input type="text" name="firstname"><br>'
                +'last_name:<input type="text" name="lastname"><br>'
                +' email:<input type="text" name="email"><br>'
                +'   phone_number:<input type="text" name="phonenumber"><br>'
                +'hire_date:<input type="text" name="hiredate"><br>'
                +'salary:<input type="text" name="salary"><br>'
                +'<input type="submit" value="Submit">'
                +'</form>'
        );
      }
    </script>
  </head>
  <body>
    <h2>使用html原生表格标签来展示数据</h2>
    <table id="display" border="1" cellspacing="0" cellpadding="3">

    </table>
    <div id="addOrUpate">

    </div>
  </body>
</html>

这篇博客涉及的完整项目在这里下载

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值