关于经典开源框架STRUTS2的使用

关于STRUTS的技术文章我很早就想写一篇了,只是不知道要写些什么东西,主要是以前没怎么接触过这个框架,因此打算用熟了之后再来写,可能感受会更深一些;其实等我会了之后,依然不知道要写些什么东西,因为总感觉都很简单的样子,没什么重点可述;但基于之前在《Jsp学习——filter的使用》一文中谈到了STRUTS2的原理,在最后也说道:”struts2的配置文件中没有servlet类的配置,只有一个filter的配置,由此可以看出其用filter处理所有的消息,至于如何处理前台传来的各种消息,我会在下一篇文章中详细阐述“ 。所以打算不管如何,这篇文章还是要写的,曾经不知在哪看到过这样一句话:”Writing was invented by someone who was too lazy to memorize“,用这句话来阐释我写技术博客的原因再好不过了。废话不多说了,开始进入主题了。

我在写《Jsp学习——servlet详解》这篇文章时候,使用了MVC架构模式来阐述那个DEMO,而STRUTS2也是公认的经典MVC框架,其使用一个filter和action类来充当控制层(control),使用JSP来充当视图层(view),使用DAO+SERVICE来充当模型层(model),整个执行流程大概是:浏览器收到用户的请求ACTION,发送到服务器端,FILTER将接收到的ACTION与特定视图关联(关联的物理视图和逻辑视图的关系全在配置文件中设置),之后继续将ACTION转发到指定的ACTION-CLASS中去处理,ACTION-CLASS调用MODEL层来完成所有的业务逻辑处理,之后再根据FILTER指定的视图资源跳转到对应的物理视图。

对于STURTS2的配置,由于其整个框架只使用了一个FILTER来充当核心控制器,而没有使用任何SERVLET,所以只需配置一下FILTER就行了,其配置方法与配置FILTER没太大差别,只是FILTER类是STRUTS2指定的框架中实现了的类(org.apache.struts2.dispatcher.FilterDispatcher),而不能由我们自己乱定。如下所示,在web.xml文件中的关键代码:

  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
对于逻辑视图与物理视图对应关系的配置文件,其文件名默认为struts.xml,当放在src目录下,如果放在同web.xml的同目录下是不会起作用的,运行时期会出很多难以预料的错误。关于其配置方式,有很多种,可以专门写一篇博文来讨论了,在这里,我暂且用我认为较简单而且易用的方式,其内容如下:

<struts>
	<package name="com.struts2.projection.action" extends="struts-default">
		<action name="*" class="com.struts2.projection.action.Action" method="{1} ">
			<result name="success">success.jsp</result>
			<result name="error">error.jsp</result>
		</action>
	</package> 
</struts>
这种方式是通过指定通配符的方式,”*“意思是对于前台传来的所有.action消息,都将分配给com.struts2.projection.action.Action类来处理,这是个自定义类,至于具体再分配给哪个方法,由method = "{1}"来指示,其意思是指定前面action的name属性中第一个*号所代表的单词为该action对应的方法名,如:前台传来login.action,则对应的处理方法为login(),传来regist.action,则对应的处理方法为regist();

另外还有一种常用的方式,同样很受欢迎,即将action名改为以 类名+!+动作名  的方式来动态调用aciton类中的方法,其动作名就是指定的方法名。在这种方式下,struts.xml的配置为一般型的配置:

<struts>
	<package name="com.struts2.projection.action" extends = "struts-default">
		<action name="login" class="com.struts2.projection.action.Action">
			<result name="error">/error.jsp</result>
			<result name="success">/success.jsp</result> 
		</action>
	</package>
</struts>
如此依然可以实现动态调用,但对ACTION类的要求是,其必须有一个默认的excute()方法。这种方法在前台为ajax框架或类似的框架如extjs中经常被很多人青睐。还有很多其它不常用的方式在此就不详细阐述。

以下是一个登陆框的完整示例:

view:index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  <body>
	<s:form action = "login" method="login">
		<s:textfield name="username" label="user name"></s:textfield>
		<s:textfield name="userpassword" label="user password"></s:textfield>
		<s:submit value="login"></s:submit>
		<s:submit value="regist" οnclick="regist()"></s:submit>
	</s:form> 
	<script type="text/javascript">
  	function regist()
  	{
  		targetForm = document.forms[0];
  		targetForm.action = "regist.action";	
  	}
  	</script>   
  </body>
</html>

web.xml

<?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">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
struts.xml

<?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>
	 <package name="com.struts2.projection.action" extends="struts-default">
		<action name="*" class="com.struts2.projection.action.Action" method="{1} ">
			<result name="success">success.jsp</result>
			<result name="error">error.jsp</result>
		</action>
	</package>  
</struts>
control:Action.java

package com.struts2.projection.action;

import java.sql.*;

import com.opensymphony.xwork2.ActionContext;
import com.struts2.projection.dao.DbDao;

public class Action {
	private String userpassword;
	private String username;
	
	public String getUserpassword() {
		return userpassword;
	}
	public void setUserpassword(String userpassword) {
		this.userpassword = userpassword;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String regist() throws ClassNotFoundException, SQLException
	{
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/test_db"; 
		String user = "root";
		String pass = "900622";
		DbDao dao = DbDao.instance(driver,url,user,pass);  
		ActionContext actionContext = ActionContext.getContext(); 
		if(username.replace(" ", "").equals("") || userpassword.replace(" ", "").equals(""))
		{
			actionContext.put("tip", "客户端提示:user name or user password can not be blank!");
			return "error";
		}
		String insertSql = "insert into user_information(username,userpassword) values('"+ username +"','"+ userpassword +"')";
		System.out.println(username+";"+userpassword);
		dao.insert(insertSql);
		actionContext.put("tip", "服务器提示: regist success!");
		return "error";
	}
	public String login() throws ClassNotFoundException, SQLException
	{
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/test_db"; 
		String user = "root";
		String pass = "900622";
		DbDao dao = DbDao.instance(driver,url,user,pass);  
		ActionContext actionContext = ActionContext.getContext(); 
        String sql = "select userpassword from user_information where username = '" + username + "'";  
        ResultSet resultSet = dao.query(sql);  
          
        if(resultSet.next())  
        {  
            if(resultSet.getString("userpassword").equals(userpassword))  
            {  
            	Integer counter=(Integer)actionContext.getApplication().get("counter");
        		if(counter == null)
        		{
        			counter=1;
        		}
        		else
        		{
        			counter++;
        		}
       			actionContext.getApplication().put("counter", counter);
    			actionContext.getSession().put("user", this.getUsername());
    			return "success";
            }  
            else  
            {  
                actionContext.put("tip", "服务器提示:password error!so login failed!");
                return "error";
            }  
        }  
        else  
        {  
            actionContext.put("tip", "服务器提示:user name not exist!");  
            return "error";
        }  
	}
}
Model:DbDao.java
package com.struts2.projection.dao;
import java.sql.*;  
public class DbDao {  
    private static DbDao dao;  
    private Connection conn;  
    private String driver;  
    private String url;  
    private String username;  
    private String pass;  
      
    private DbDao()  
    {}  
      
    private DbDao(String driver,String url,  
            String username,String pass)  
    {  
        this.driver = driver;  
        this.url = url;  
        this.username = username;  
        this.pass = pass;  
    }  
  
    public static DbDao getDao() {  
        return dao;  
    }  
  
    public static void setDao(DbDao dao) {  
        DbDao.dao = dao;  
    }  
  
    public String getDriver() {  
        return driver;  
    }  
  
    public void setDriver(String driver) {  
        this.driver = driver;  
    }  
  
    public String getUrl() {  
        return url;  
    }  
  
    public void setUrl(String url) {  
        this.url = url;  
    }  
  
    public String getUsername() {  
        return username;  
    }  
  
    public void setUsername(String username) {  
        this.username = username;  
    }  
  
    public String getPass() {  
        return pass;  
    }  
  
    public void setPass(String pass) {  
        this.pass = pass;  
    }  
      
    public void getConnection() throws ClassNotFoundException, SQLException  
    {  
        if(conn == null)  
        {  
            Class.forName(this.driver);  
            conn = DriverManager.getConnection(url, username, pass);  
        }  
    }  
      
    public static DbDao instance(String driver,String url,  
            String username,String pass)  
    {  
        if(dao == null)  
        {  
            dao = new DbDao(driver,url,username,pass);  
        }  
        return dao;  
    }  
      
    public boolean insert(String sql) throws ClassNotFoundException, SQLException  
    {  
        getConnection();  
        Statement statement = conn.createStatement();  
        if(statement.executeUpdate(sql) != -1)  
        {  
            return false;  
        }  
        return true;  
    }  
      
    public ResultSet query(String sql) throws ClassNotFoundException, SQLException  
    {  
        getConnection();  
        Statement statement = conn.createStatement();  
        return statement.executeQuery(sql);  
    }  
      
    public void delete(String sql) throws ClassNotFoundException, SQLException  
    {  
        getConnection();  
        Statement statement = conn.createStatement();  
        statement.executeUpdate(sql);  
    }  
      
    public void update(String sql) throws ClassNotFoundException, SQLException  
    {  
        getConnection();  
        Statement statement = conn.createStatement();  
        statement.executeUpdate(sql);  
    }  
}  


最后,说一下Action.java类,对于Action.java的成员变量,我需要特意说明一下:Action类中必须要声明与前台交互的数据,并且数据的标示符与前台定义的要相同,另外要定义setter和getter函数,因为Action与前台打交道就是通过filter和拦截器来控制这几个值,当前台传来值时,拦截器就调用setter方法来设置对应的成员值。

Action.java可以继承默认的SupportAction类作为其父类,SupportAction中实现了一些一般情形的响应,继承之后,就可以使用其中方法或者重写其中方法来达到自己的需求。(在这里,我没有继承SupportActoin类)。

当然的,代码的分层结构还不够好,因为Action中依然有许多的逻辑处理,在标准的SSH框架中,DbDao上面还有一层Service类,来处理脱离数据库之外的逻辑,因为这里暂且只介绍了Struts2,所以分层并不是很标准。






  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值