zoukankan      html  css  js  c++  java
  • 模拟Struts2实现

    本文主要是一个模拟的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. 取配置参数,如果你请求的地址以actiondo空结尾的话,才真正过滤。
    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"};//你请求的地址以actiondo空结尾的话,才真正过滤。默认值
                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";
            }
        }
    }

    完成

  • 相关阅读:
    数据访问之注册审核(重点是审核!!!)常用于企业、公司、医院等网站---2017-05-04
    5个简约的网站---2017-05-03
    数据访问(租房子多条件查询)---2017-05-03
    数据访问之 批量删除 ---2017-05-03
    数据访问之查询数据 ---2017--05-02
    php部分--数组(包含指针思想遍历数组);
    php部分---面向对象静态、抽象类、oop接口、加载类、魔术方法、关键字。
    PHP部分---字符串处理(文中例子不断更新);
    php部分--面向对象三大特性-封装(另加连续调用的一个例子)、继承(重写、重载的例子)、多态;
    php部分---面向对象:定义、实例化、构造函数、析构函数;
  • 原文地址:https://www.cnblogs.com/jjx2013/p/6223691.html
Copyright © 2011-2022 走看看