模拟Struts2实现

来源:互联网 发布:幸运28精准单双算法 编辑:程序博客网 时间:2024/04/27 21:58

本文主要是一个模拟的Struts2的简单实现

真正的MVC架构

这里写图片描述

实现主要思路

定义一个过滤器,接收传递过去的Action,根据处理的结果重定向或者转发。

首先定义index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title></title>    <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">        <!--    <link rel="stylesheet" type="text/css" href="styles.css">    -->  </head>  <body>    <form action="${pageContext.request.contextPath}/addCustomer.action" method="post">        姓名:<input type="text" name="name"/><br/>        年龄:<input type="text" name="age"/><br/>        <input type="submit" value="保存"/>    </form>  </body></html>

在web.xml中配置过滤器

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  <display-name>MyStruct2</display-name>  <filter>        <filter-name>CenterFilter</filter-name>        <filter-class>cn.itcast.framework.core.CenterFilter</filter-class><!--        <init-param>--><!--            <param-name>aciontPostFix</param-name>--><!--            <param-value>action,do</param-value>--><!--        </init-param>-->    </filter>    <filter-mapping>        <filter-name>CenterFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>  <welcome-file-list>    <welcome-file>index.html</welcome-file>    <welcome-file>index.htm</welcome-file>    <welcome-file>index.jsp</welcome-file>    <welcome-file>default.html</welcome-file>    <welcome-file>default.htm</welcome-file>    <welcome-file>default.jsp</welcome-file>  </welcome-file-list></web-app>

核心配置文件

<?xml version="1.0" encoding="UTF-8"?><!-- 核心配置文件 --><framework>    <!--     action:        name:必须有,且唯一。如同之前请求的什么operation        class:必须有,要执行哪个JavaBean的类名        method:可以没有。没有的话就是默认值execute。JavaBean中对应的操作方法。该方法的特点是:public String addCustomer(){}     -->    <action name="addCustomer" class="cn.itcast.domain.Customer" method="addCustomer">        <!--         result:代表着一种结果。            type:可以没有,默认是dispatcher。转向目标的类型。dispatcher代表着请求转发            name:必须有。对应的是JavaBean中addCustomer的返回值            主体内容:必须有。目标资源的URI        -->        <result type="redirect" name="success">/success.jsp</result>        <result type="dispatcher" name="error">/error.jsp</result>    </action>    <action name="updateCustomer" class="cn.itcast.domain.Customer" method="updateCustomer">        <result type="dispatcher" name="success">/success.jsp</result>    </action></framework>

核心过滤器实现

  1. 初始化配置文件,读取XML配置文件:把配置文件中的信息封装到对象中.再放到actions中
  2. 取配置参数,如果你请求的地址以action\do\空结尾的话,才真正过滤。
  3. 解析用户请求的URI,截取后缀名,看看是否需要我们的框架进行处理
  4. 如果需要框架处理,解析uri中的动作名称,获得相应方法处理
  5. 根据结果中的type决定是转发还是重定向,重定向的目标就是结果中的targetUri
package cn.itcast.framework.core;import java.io.IOException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.beanutils.BeanUtils;import org.dom4j.Document;import org.dom4j.Element;import cn.itcast.framework.util.Dom4JUtil;public class CenterFilter implements Filter {    //存取配置文件信息。key:对应action中的name value:Action对象    private Map<String, Action> actions = new HashMap<String, Action>();    private FilterConfig filterConfig;    public void init(FilterConfig filterConfig) throws ServletException {        initCfg();//初始化配置文件        this.filterConfig = filterConfig;    }    //初始化配置文件    private void initCfg() {        //读取XML配置文件:把配置文件中的信息封装到对象中.再放到actions中        Document document = Dom4JUtil.getDocument();        Element root = document.getRootElement();        //得到所有的action元素,创建Action对象,封装信息        List<Element> actionElements = root.elements("action");        if(actionElements!=null&&actionElements.size()>0){            for(Element actionElement:actionElements){                //封装action信息开始                Action action = new Action();                action.setName(actionElement.attributeValue("name"));                action.setClassName(actionElement.attributeValue("class"));                String methodXmlAttrValue = actionElement.attributeValue("method");                if(methodXmlAttrValue!=null)                    action.setMethod(methodXmlAttrValue);                //封装action信息结束                //得到每个action元素中的result元素,创建Result对象,封装信息                //封装属于当前action的结果                List<Element> resultElements = actionElement.elements("result");                if(resultElements!=null&&resultElements.size()>0){                    for(Element resultElement:resultElements){                        Result result = new Result();                        result.setName(resultElement.attributeValue("name"));                        result.setTargetUri(resultElement.getText().trim());                        String typeXmlValue = resultElement.attributeValue("type");                        if(typeXmlValue!=null){                            result.setType(ResultType.valueOf(typeXmlValue));                        }                        action.getResults().add(result);                    }                }                //封装属于当前action的结果                //把Action对象都放到Map中                actions.put(action.getName(), action);            }        }    }    public void doFilter(ServletRequest req, ServletResponse resp,            FilterChain chain) throws IOException, ServletException {        try {            HttpServletRequest request = (HttpServletRequest)req;            HttpServletResponse response = (HttpServletResponse)resp;            //真正的控制器部分            //取一个配置参数            String aciontPostFixs [] = {"action","","do"};//你请求的地址以action\do\空结尾的话,才真正过滤。默认值            String aciontPostFix = filterConfig.getInitParameter("aciontPostFix");            if(aciontPostFix!=null){                aciontPostFixs = aciontPostFix.split("\\,");            }            //解析用户请求的URI            String uri = request.getRequestURI();//   /strutsDay01MyFramework/addCustomer.action            //截取后缀名,看看是否需要我们的框架进行处理            //切后缀名            String extendFileName = uri.substring(uri.lastIndexOf(".")+1);// /strutsDay01MyFramework/addCustomer.action   action                                                                            // /strutsDay01MyFramework/addCustomer.do   do                                                                            // /strutsDay01MyFramework/addCustomer   ""            boolean needProcess = false;            for(String s:aciontPostFixs){                if(extendFileName.equals(s)){                    needProcess = true;                    break;                }            }            if(needProcess){                //需要框架处理                //解析uri中的动作名称                String requestActionName = uri.substring(uri.lastIndexOf("/")+1, uri.lastIndexOf("."));                System.out.println("您的请求动作名是:"+requestActionName);                //查找actions中对应的Action对象                if(actions.containsKey(requestActionName)){                    Action action = actions.get(requestActionName);                    //得到类名称的字节码                    Class clazz = Class.forName(action.getClassName());                    //封装数据到JavaBean中,利用BeanUtils框架                    Object bean = clazz.newInstance();                    BeanUtils.populate(bean, request.getParameterMap());                    //实例化,调用其中指定的方法名称                    Method m = clazz.getMethod(action.getMethod(), null);                    //根据方法的返回值,遍历结果                    String resultValue = (String)m.invoke(bean, null);                    List<Result> results = action.getResults();                    if(results!=null&&results.size()>0){                        for(Result result:results){                            if(resultValue.equals(result.getName())){                                //根据结果中的type决定是转发还是重定向                                //重定向的目标就是结果中的targetUri                                if("dispatcher".equals(result.getType().toString())){                                    //转发                                    request.getRequestDispatcher(result.getTargetUri()).forward(request, response);                                }                                if("redirect".equals(result.getType().toString())){                                    //重定向                                    response.sendRedirect(request.getContextPath()+result.getTargetUri());                                }                            }                        }                    }                }else{                    throw new RuntimeException("The action "+requestActionName+" is not founded in your config files!");                }            }else{                chain.doFilter(request, response);            }        } catch (Exception e) {            throw new RuntimeException(e);        }    }    public void destroy() {    }}

javabean如下

package cn.itcast.domain;import java.io.Serializable;public class Customer implements Serializable {    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String addCustomer(){        if("wzhting".equals(name)){            return "success";        }else{            return "error";        }    }}

完成

0 0
原创粉丝点击