Struts的ActionServlet模拟实现

Struts的ActionServlet模拟实现

Struts中,ActionServlet作为总控Servlet接受请求并转发到各Action,它的原理并不复杂,本文即展示了ActionServlet模拟实现过程。

首先,在Web.xml中配置,让所有url带.go(struts用的do我用go,特意区分一下)的请求都让DispatchServlet处理,DispatchServlet就是ActionServlet模拟实现类.

<? xml version="1.0" encoding="UTF-8" ?>
< web-app  version ="2.4"  xmlns ="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>

    
<!--  welcome.jsp  -->
    
< welcome-file-list >
        
< welcome-file > /web/page/first.jsp </ welcome-file >
    
</ welcome-file-list >

    
<!--  DispatchServlet  -->
    
< servlet >
        
< servlet-name > DispatchServlet </ servlet-name >
        
< servlet-class >
            com.sitinspring.action.DispatchServlet
        
</ servlet-class >
        
< init-param >
            
< description > Configuration File </ description >
            
< param-name > configFile </ param-name >
            
< param-value > web-inf\mockStruts-config.xml </ param-value >
        
</ init-param >
    
</ servlet >

    
< servlet-mapping >
        
< servlet-name > DispatchServlet </ servlet-name >
        
< url-pattern > *.go </ url-pattern >
    
</ servlet-mapping >
</ web-app >


上面指定了DispatchServlet的初始化参数,DispatchServlet将用它找到配置文件mockStruts-config.xml,这个文件模拟对应着Struts-config.xml.

DispatchServlet的代码如下:

package  com.sitinspring.action;

import  javax.servlet.ServletConfig;
import  javax.servlet.ServletContext;
import  javax.servlet.ServletException;
import  javax.servlet.http.HttpServlet;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;

import  com.sitinspring.util.ServletFinder;
import  com.sitinspring.util.StringUtil;

/**
 * 用于分发命令到其它Servlet的总控Servlet
 * 
@author  sitinspring
 *
 * @date 2008-2-12
 
*/
public   class  DispatchServlet  extends  HttpServlet {
    
private   static   final   long  serialVersionUID  =   56890894234786L ;

    
public   void  doPost(HttpServletRequest request, HttpServletResponse response)
            
throws  ServletException, java.io.IOException {
        request.setCharacterEncoding(
" UTF-8 " );

        
//  通过ServletContext取得工程的绝对物理路径
        ServletContext sct  =  getServletContext();
        String realPath 
=  sct.getRealPath( " / " );
        
        
//  通过ServletConfig实例取得初始化参数configFile
        ServletConfig config = this .getServletConfig();        
        String mockStrutsCfgFile
= config.getInitParameter( " configFile " );
        
        
//  组合配置文件全物理路径
        mockStrutsCfgFile = realPath + mockStrutsCfgFile;
        
        
//  取得请求的URI
        String reqUri = request.getRequestURI();
        
        
//  取得模式匹配字符串,即go,do等
        String patternStr;
        
if (reqUri.contains( " ? " )){
            patternStr
= StringUtil.getMatchedString( " ([.])(.*)? " ,reqUri);
        }
        
else {
            patternStr
= StringUtil.getMatchedString( " ([.])(.*)$ " ,reqUri);
        }

        
//  取得下一个处理请求的Servlet名
        String servletName = StringUtil.getMatchedString( " /(.*)/(.*)[.] " + patternStr,reqUri);
        
        
//  以Servlet名为基础从设定文件中取得响应的Servlet类名
        ServletFinder finder = new  ServletFinder(mockStrutsCfgFile,servletName);        
        String servletClass
= finder.getServletClass();
        
        
try  {
            
//  通过反射调用真正的Servlet类进行处理
            Class cls = Class.forName(servletClass);
            HttpServlet servlet
= (HttpServlet)cls.newInstance();
            servlet.service(request, response);
        } 
catch  (Exception e) {
            e.printStackTrace();
        }
    }
        
    
public   void  doGet(HttpServletRequest request, HttpServletResponse response)
            
throws  ServletException, java.io.IOException {
        doPost(request, response);
    }
}


上面的注释应该说得比较清楚了,DispatchServlet的作用就是解析URI中的ServletName,然后在文件mockStruts-config.xml中以此查找对应的Servlet类,然后用反射生成它的实例处理用户请求.解析的过程借助了正则表达式,查找XML的过程借助了dom4j.

mockStruts-config.xml文件内容如下:

<? xml version="1.0" encoding="GBK" ?>

< servlets >
    
<!--  处理登录的Servlet  -->
    
< servlet >
        
< name > login </ name >
        
< class > com.sitinspring.action.LoginServlet </ class >
    
</ servlet >
    
    
<!--  处理注册的Servlet  -->
    
< servlet >
        
< name > register </ name >
        
< class > com.sitinspring.action.RegisterServlet </ class >
    
</ servlet >
    
    
<!--  处理翻页的Servlet  -->
    
< servlet >
        
< name > ShowPage </ name >
        
< class > com.sitinspring.action.ShowPageServlet </ class >
    
</ servlet >
</ servlets >


接下来诸个Servlet类处理请求没有什么特别的,你想怎么处理就怎么处理,在下面的Servlet中是找出了提交的所有参数并在后即页面中展示.

package  com.sitinspring.action;

import  java.util.Enumeration;
import  java.util.Hashtable;
import  java.util.Map;

import  javax.servlet.RequestDispatcher;
import  javax.servlet.ServletException;
import  javax.servlet.http.HttpServlet;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;

/**
 * 用于登录处理的Servlet
 * 
@author  sitinspring
 *
 * @date 2008-2-12
 
*/
public   class  LoginServlet  extends  HttpServlet {
    
private   static   final   long  serialVersionUID  =   56890894234786L ;

    
public   void  doPost(HttpServletRequest request, HttpServletResponse response)
            
throws  ServletException, java.io.IOException {
        request.setCharacterEncoding(
" UTF-8 " );
        
        Map
< String,String >  ht = new  Hashtable < String,String > ();
        
        
//  取得输入参数并存入哈希表
        Enumeration params = request.getParameterNames();        
        
while (params.hasMoreElements()){
            String key
= (String)params.nextElement();            
            String value
= request.getParameter(key);
            
            ht.put(key, value);
        }
        
        request.setAttribute(
" ht " , ht);

        RequestDispatcher dispatcher 
=  request.getRequestDispatcher( " /web/page/loginResult.jsp " );
        dispatcher.forward(request, response);
        
return ;
    }
        
    
public   void  doGet(HttpServletRequest request, HttpServletResponse response)
            
throws  ServletException, java.io.IOException {
        doPost(request, response);
    }
}


显示结果的jsp页面代码:

<% @ page contentType = " text/html; charset=UTF-8 " %>
<% @page language = " java "  import = " java.util.Map " %>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< html >
< head >
< title > "MockStruts"-loginResult页面 </ title >
< meta  http-equiv ="Content-Type"  content ="text/html; charset=UTF-8" >
< script  src ="web/js/ajax.js"  type ="text/javascript" ></ script >
< link  rel ="stylesheet"  rev ="stylesheet"  href ="web/css/style.css"
    type
="text/css"   />
</ head >

< body >     
    
<%
        Map
< String , String >  ht = (Map < String , String > )request.getAttribute( " ht " );    
    
        
for ( String  key:ht.keySet()){
            
String  value = ht.get(key);
            
            out.print(
" <p>参数名: " + key + "  参数值: " + value + " </p> " );
        }
    
%>
</ body >
</ html >
 
发效果之一(通过form提交请求):



转发效果之二(通过链接提交请求):


 
 
 
本文代码下载(请在lib中加入dom4j-1.6.1.jar并载入到工程的库中):
http://www.blogjava.net/Files/sitinspring/MockStruts20080329004955.zip

猜你喜欢

转载自chenyajie.iteye.com/blog/1976530