由于这几天到处出差,比较忙,博客的更新速度比较慢。今天的这个是小实例的功能和上一篇博文中的功能是一致的,只是将原来由servlet实现的部分功能用前一段时间比较流行的struts2框架来实现,而现在比较流行的是Spring MVC,这个在以后也会专门来写一篇博文。
这次要使用struts2来完成前台到后台的映射,所以要先搭建struts2的环境。
首先要导入struts2依赖的jar包,这里还是和以前一样,使用手动导入的方式,所以要先下载到需要的jar,这些jar包可以去struts2的官网上下载。但是struts2运行必须需要的jar包如下:
将这个jar放在WEB-INF下的lib目录下,并且将该目录添加到运行环境中。
接下来要在web.xml中配置StrutsPrepareAndExecuteFilter,web.xml的配置如下:
<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>struts2filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
filter>
<filter-mapping>
<filter-name>struts2filter-name>
<url-pattern>*.actionurl-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
在以上的代码中,实现了对数据的增删改查操作,这和之前的servlet比起来要简洁了好多。这段代码和之前的servlet还有一个重要的不同点,就在没有在代码中执行重定向的操作,而这个操作可以直接交给struts2框架来完成。注意:在使用struts2时要正确使用void和String 的返回值类型,当需要根据程序执行状态跳转页面时要使用String的返回值类型,就像本项目中的增删改操作;当只是需要获取数据不要判断状态跳转页面时,要使用void的返回值类型,就像本项目中的查询操作。
Action编写完毕后,项目还是不能成功运行的,还需要告诉struts2要如何执行Action中的方法,这就需要配置struts2的配置文件,struts2的配置文件名称默认为struts.xml,并且需要放在编译文件的根目录下,如果在项目中没有使用默认的路径或文件名称,则需要在web.xml中配置StrutsPrepareAndExecuteFilter时再配一个init-param的节点。在本项目中使用的是默认的文件名和路径。struts.xml的配置如下:
<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.jspresult>
action>
package>
struts>
在struts2的配置文件中,首先要将开发模式设置成true,不认在struts.xml配制的代码不会立即生效。接着就是配制Action的访问映射,在这个映射的配制中我使用了通配符来简化配制。如果不使用通配符,增删改查每一个方法都需要单独配制。上面的配制等效以下配制:
<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.jspresult>
action>
<action name="update" class="com.leo.action.UserAction" method="update">
<result name="success">/index.jspresult>
action>
<action name="delete" class="com.leo.action.UserAction" method="delete">
<result name="success">/index.jspresult>
action>
package>
struts>
灵活的使用通配符能提高代码的编写效率,在未来修改起来也比较方便。
还要说明的是这个result标签,前面提到的页面的跳转是交给struts2来完成的,这个result就是用来判断返回值的,如果action的返回值和result的name属性值一致,则跳转到result指定的页面。
到这里程序的编写全部完成了,程序的运行结果如下:
这里还发现一个很重要的问题,这也是之前的遗留下来的问题,那就是转发和重定向的区别。从截图上可以看到,地址栏在执行完插入操作后发生了变化,但是页面显示的类型却还是index.jsp的内容。这样就会导致一个问题,当我来这种情况下执行刷新操作时,程序会再一次执行插入操作,而我的本意只是想刷新当前的index.jsp页面。出现这种问题是因为result的跳转页面默认使用的是转发的方式,而要解决这个问题,就需要我们将result跳转页面的方式设置成重定向的方式。修改过后的代买如下:
<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.jspresult>
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(" employee_id first_name last_name email phone_number hire_date salary operator ");
for(var i in data){
$("#display").append(" "+data[i].employeeid+" "+data[i].firstname+" "+data[i].lastname+" "+data[i].email+" "+data[i].phonenumber+" "+data[i].hiredate+" "+data[i].salary+" update|add|delete ");
}
}
});
})
function update(index) {
alert(global[index].employeeid);
$("#addOrUpate").html("");
$("#addOrUpate").html('
);
}
function add() {
$("#addOrUpate").html("");
$("#addOrUpate").html('
);
}
script>
head>
<body>
<h2>使用html原生表格标签来展示数据h2>
<table id="display" border="1" cellspacing="0" cellpadding="3">
table>
<div id="addOrUpate">
div>
body>
html>
这篇博客涉及的完整项目在这里下载