关于经典开源框架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文件中的关键代码:

  1. <filter> 
  2.     <filter-name>struts2</filter-name> 
  3.     <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> 
  4. </filter> 
  5. <filter-mapping> 
  6.     <filter-name>struts2</filter-name> 
  7.     <url-pattern>/*</url-pattern> 
  8. </filter-mapping> 
  <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的同目录下是不会起作用的,运行时期会出很多难以预料的错误。关于其配置方式,有很多种,可以专门写一篇博文来讨论了,在这里,我暂且用我认为较简单而且易用的方式,其内容如下:

  1. <struts> 
  2.     <package name="com.struts2.projection.action" extends="struts-default"> 
  3.         <action name="*" class="com.struts2.projection.action.Action" method="{1} "> 
  4.             <result name="success">success.jsp</result> 
  5.             <result name="error">error.jsp</result> 
  6.         </action> 
  7.     </package>  
  8. </struts> 
<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的配置为一般型的配置:

  1. <struts> 
  2.     <package name="com.struts2.projection.action" extends = "struts-default"> 
  3.         <action name="login" class="com.struts2.projection.action.Action"> 
  4.             <result name="error">/error.jsp</result> 
  5.             <result name="success">/success.jsp</result>  
  6.         </action> 
  7.     </package> 
  8. </struts> 
<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

  1. <%@ page language="java" import="java.util.*" pageEncoding="gb2312"%> 
  2. <%@ taglib prefix="s" uri="/struts-tags" %> 
  3. <
  4. String path = request.getContextPath(); 
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 
  6. %> 
  7.  
  8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
  9. <html> 
  10.   <head> 
  11.     <base href="<%=basePath%>"> 
  12.     <title>My JSP 'index.jsp' starting page</title> 
  13.     <meta http-equiv="pragma" content="no-cache"> 
  14.     <meta http-equiv="cache-control" content="no-cache"> 
  15.     <meta http-equiv="expires" content="0">     
  16.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 
  17.     <meta http-equiv="description" content="This is my page"> 
  18.     <!--
  19.     <link rel="stylesheet" type="text/css" href="styles.css">
  20.     --> 
  21.   </head> 
  22.   <body> 
  23.     <s:form action = "login" method="login"> 
  24.         <s:textfield name="username" label="user name"></s:textfield> 
  25.         <s:textfield name="userpassword" label="user password"></s:textfield> 
  26.         <s:submit value="login"></s:submit> 
  27.         <s:submit value="regist" onclick="regist()"></s:submit> 
  28.     </s:form>  
  29.     <script type="text/javascript"> 
  30.     function regist() 
  31.     { 
  32.         targetForm = document.forms[0]; 
  33.         targetForm.action = "regist.action";     
  34.     } 
  35.     </script>    
  36.   </body> 
  37. </html> 
<%@ 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

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <web-app version="2.5"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
  7.   <welcome-file-list> 
  8.     <welcome-file>index.jsp</welcome-file> 
  9.   </welcome-file-list> 
  10.   <filter> 
  11.     <filter-name>struts2</filter-name> 
  12.     <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> 
  13.   </filter> 
  14.   <filter-mapping> 
  15.     <filter-name>struts2</filter-name> 
  16.     <url-pattern>/*</url-pattern> 
  17.   </filter-mapping> 
  18. </web-app> 
<?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

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <!DOCTYPE struts PUBLIC 
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
  4.     "http://struts.apache.org/dtds/struts-2.0 dtd" 
  5. > 
  6. <struts> 
  7.      <package name="com.struts2.projection.action" extends="struts-default"> 
  8.         <action name="*" class="com.struts2.projection.action.Action" method="{1} "> 
  9.             <result name="success">success.jsp</result> 
  10.             <result name="error">error.jsp</result> 
  11.         </action> 
  12.     </package>   
  13. </struts> 
<?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

  1. package com.struts2.projection.action; 
  2.  
  3. import java.sql.*; 
  4.  
  5. import com.opensymphony.xwork2.ActionContext; 
  6. import com.struts2.projection.dao.DbDao; 
  7.  
  8. public class Action { 
  9.     private String userpassword; 
  10.     private String username; 
  11.      
  12.     public String getUserpassword() { 
  13.         return userpassword; 
  14.     } 
  15.     public void setUserpassword(String userpassword) { 
  16.         this.userpassword = userpassword
  17.     } 
  18.     public String getUsername() { 
  19.         return username; 
  20.     } 
  21.     public void setUsername(String username) { 
  22.         this.username = username
  23.     } 
  24.     public String regist() throws ClassNotFoundException, SQLException 
  25.     { 
  26.         String driver = "com.mysql.jdbc.Driver"
  27.         String url = "jdbc:mysql://localhost:3306/test_db";  
  28.         String user = "root"
  29.         String pass = "900622"
  30.         DbDao dao = DbDao.instance(driver,url,user,pass);   
  31.         ActionContext actionContext = ActionContext.getContext();  
  32.         if(username.replace(" ", "").equals("") || userpassword.replace(" ", "").equals("")) 
  33.         { 
  34.             actionContext.put("tip", "客户端提示:user name or user password can not be blank!"); 
  35.             return "error"; 
  36.         } 
  37.         String insertSql = "insert into user_information(username,userpassword) values('"+ username +"','"+ userpassword +"')"; 
  38.         System.out.println(username+";"+userpassword); 
  39.         dao.insert(insertSql); 
  40.         actionContext.put("tip", "服务器提示: regist success!"); 
  41.         return "error"; 
  42.     } 
  43.     public String login() throws ClassNotFoundException, SQLException 
  44.     { 
  45.         String driver = "com.mysql.jdbc.Driver"
  46.         String url = "jdbc:mysql://localhost:3306/test_db";  
  47.         String user = "root"
  48.         String pass = "900622"
  49.         DbDao dao = DbDao.instance(driver,url,user,pass);   
  50.         ActionContext actionContext = ActionContext.getContext();  
  51.         String sql = "select userpassword from user_information where username = '" + username + "'";   
  52.         ResultSet resultSet = dao.query(sql);   
  53.            
  54.         if(resultSet.next())   
  55.         {   
  56.             if(resultSet.getString("userpassword").equals(userpassword))   
  57.             {   
  58.                 Integer counter=(Integer)actionContext.getApplication().get("counter"); 
  59.                 if(counter == null) 
  60.                 { 
  61.                     counter=1
  62.                 } 
  63.                 else 
  64.                 { 
  65.                     counter++; 
  66.                 } 
  67.                 actionContext.getApplication().put("counter", counter); 
  68.                 actionContext.getSession().put("user", this.getUsername()); 
  69.                 return "success"; 
  70.             }   
  71.             else   
  72.             {   
  73.                 actionContext.put("tip", "服务器提示:password error!so login failed!"); 
  74.                 return "error"; 
  75.             }   
  76.         }   
  77.         else   
  78.         {   
  79.             actionContext.put("tip", "服务器提示:user name not exist!");   
  80.             return "error"; 
  81.         }   
  82.     } 
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
  1. package com.struts2.projection.dao; 
  2. import java.sql.*;   
  3. public class DbDao {   
  4.     private static DbDao dao;   
  5.     private Connection conn;   
  6.     private String driver;   
  7.     private String url;   
  8.     private String username;   
  9.     private String pass;   
  10.        
  11.     private DbDao()   
  12.     {}   
  13.        
  14.     private DbDao(String driver,String url,   
  15.             String username,String pass)   
  16.     {   
  17.         this.driver = driver;   
  18.         this.url = url;   
  19.         this.username = username;   
  20.         this.pass = pass;   
  21.     }   
  22.    
  23.     public static DbDao getDao() {   
  24.         return dao;   
  25.     }   
  26.    
  27.     public static void setDao(DbDao dao) {   
  28.         DbDao.dao = dao;   
  29.     }   
  30.    
  31.     public String getDriver() {   
  32.         return driver;   
  33.     }   
  34.    
  35.     public void setDriver(String driver) {   
  36.         this.driver = driver;   
  37.     }   
  38.    
  39.     public String getUrl() {   
  40.         return url;   
  41.     }   
  42.    
  43.     public void setUrl(String url) {   
  44.         this.url = url;   
  45.     }   
  46.    
  47.     public String getUsername() {   
  48.         return username;   
  49.     }   
  50.    
  51.     public void setUsername(String username) {   
  52.         this.username = username;   
  53.     }   
  54.    
  55.     public String getPass() {   
  56.         return pass;   
  57.     }   
  58.    
  59.     public void setPass(String pass) {   
  60.         this.pass = pass;   
  61.     }   
  62.        
  63.     public void getConnection() throws ClassNotFoundException, SQLException   
  64.     {   
  65.         if(conn == null)   
  66.         {   
  67.             Class.forName(this.driver);   
  68.             conn = DriverManager.getConnection(url, username, pass);   
  69.         }   
  70.     }   
  71.        
  72.     public static DbDao instance(String driver,String url,   
  73.             String username,String pass)   
  74.     {   
  75.         if(dao == null)   
  76.         {   
  77.             dao = new DbDao(driver,url,username,pass);   
  78.         }   
  79.         return dao;   
  80.     }   
  81.        
  82.     public boolean insert(String sql) throws ClassNotFoundException, SQLException   
  83.     {   
  84.         getConnection();   
  85.         Statement statement = conn.createStatement();   
  86.         if(statement.executeUpdate(sql) != -1)   
  87.         {   
  88.             return false;   
  89.         }   
  90.         return true;   
  91.     }   
  92.        
  93.     public ResultSet query(String sql) throws ClassNotFoundException, SQLException   
  94.     {   
  95.         getConnection();   
  96.         Statement statement = conn.createStatement();   
  97.         return statement.executeQuery(sql);   
  98.     }   
  99.        
  100.     public void delete(String sql) throws ClassNotFoundException, SQLException   
  101.     {   
  102.         getConnection();   
  103.         Statement statement = conn.createStatement();   
  104.         statement.executeUpdate(sql);   
  105.     }   
  106.        
  107.     public void update(String sql) throws ClassNotFoundException, SQLException   
  108.     {   
  109.         getConnection();   
  110.         Statement statement = conn.createStatement();   
  111.         statement.executeUpdate(sql);   
  112.     }   
  113. }   
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,所以分层并不是很标准。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值