struts2学习笔记一:一个迷你的Struts

该笔记跟着视频走的,用于回头看,没啥料。

在这个笔记中,主要完成一个迷你的struts,所需要的知识点也不是很多,其一是反射,其二是过滤器,其三就是xml的dom4j解析了。

1、回顾反射
什么是反射?反射就是运行时动态加载类,生成对应的Class对象,然后通过Class对象去做一些我们想做的事情(我乱扯的。)
其实以我个人的理解就是要熟练的使用好反射对应的一些API就可以了,诸如如何生成Class啊,获得对象的方法啊,生成对应的Class的对象啊等等。

a)通过字符串获得Class对象
Class<?> clazz = Class.forName("类的全名");

b)获得实例
Object obj = clazz.newInstance();

c)通过生成的Class对象,获取类中具体的方法,根据方法的名称
Method method = clazz.getMethod("方法名");

d)执行具体的方法
method.invoke("需要用上作用的对象obj",方法的参数);

2、回顾xml的解析

 关于xml的解析有多种多样,比较常用的就是dom4j了。但是由于我个人的能力问题,我经常会忘记如何去使用(将它和其他的解析搞混,比如创建工厂:我会分不清该使用SaxReader还是使用SaxBuilder。。。)
 总之还是那句话,要时常练。

3、回顾Filter过滤器

过滤器过滤器,它的作用到底是什么呢?它主要是用于过滤来自浏览器发送来的请求,它会在service()方法被调用之前先处理一次(在请求到达访问资源自谦,会先经过过滤器)。过滤器的主要功能是可以帮助我们完成一些批处理,比如要记录以下每个Servlet执行的时间啊,设置一下字符编码啊等等,还可以根据filterChain来决定是否放行。**当然也可以使用请求转发或者重定向,不让请求到达目的地!**

好了,下面还是进入正常的节目吧:自定义了一个mini的struts,既然是迷你的struts,功能当然很简陋,将就着看吧:
这是我这个mini的struts项目的大致结构

这里写图片描述

**

  1. 第一步:当然是导入jar包啊,在没有学习Maven之前,所有的项目都要这样先导一遍,这个项目只需要导入两个jar包:一个dom4j的jar文件,另一个用于支持xpath的jar文件(注意了:这个xpath可是一个好东西,要学会怎么使用噢!)
  2. 第二步:在src下(也就是classpath)下新建一个xml文件,这个xml可以随便取名字,但是既然在这里是用于模拟struts的,那么就将其命名为struts.xml吧。
  3. 第三步:新建一个action,就叫它HelloAction吧,一个普通的Java类(你也可以叫他POJO,Plain Ordinary Java Object),在它里面主要定义了一个方法,你看:这里写图片描述
    方法名一般叫execute,但是为了表示我的与众不同,我取名为invoke,很简单就是返回一个字符串。
  4. 然后需要在struts.xml文件中进行配置:
    这里写图片描述
    这个配置文件中的玩意我们解析xml文件的时候都可以得到,然后通过得到的信息通过反射创建对象,然后调用方法,看看方法的返回值是否是success,然后在跳转到result标签中的/index.jsp页面中。
  5. 下面进行编码第一步,创建一个用于解析xml文件的类,叫做ConfigManager:
package com.hardstudy.utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.hardstudy.entities.ActionConfig;
import com.hardstudy.entities.ResultConfig;

public class ConfigManager {
    public static Map<String, ActionConfig> getActionConfig(){
        Map<String,ActionConfig> map = new HashMap<>();
        //1:使用dom4j进行解析
            //a:生成解析器工厂
        SAXReader reader = new SAXReader();
        try {
            //b:解析struts.xml文件得到document对象
            Document document = reader.read(ConfigManager.class.getResourceAsStream("/struts.xml"));

            //c:使用xpath快速进行解析,明确目的,现在已经加载到了struts.xml文件,要做的就是获得action标签,但是这样的标签,在struts.xml文件中可能有多个,所以需要将这个标签及其内容封装到一个List中
            //得到所有的action标签
            List<Element> elements = document.selectNodes("//action");

            //循环每个action标签,将它们封装成一个ActionConfig对象
            for(Element element : elements){
                ActionConfig config = new ActionConfig();
                config.setName(element.attributeValue("name"));
                config.setClazz(element.attributeValue("class"));
                config.setMethod(element.attributeValue("method"));

                //一个action中可能有若干个result标签,现在由action标签得到它下面的所有的result子元素
                List<Element> results = element.elements("result");
                Map<String, ResultConfig> resultMaps = new HashMap<>();
                for(Element result : results){
                    ResultConfig resultConfig = new ResultConfig();
                    resultConfig.setName(result.attributeValue("name"));
                    resultConfig.setTarget(result.getText());
                    //将所有的result标签中存到Map
                    resultMaps.put(resultConfig.getName(), resultConfig);
                }
                config.setResults(resultMaps);
                map.put(config.getName(), config);
            }
        } catch (DocumentException e) {
            throw new RuntimeException("文件找不到,请重新确认!");
        }
        return map;
    }
}

6、在解析的时候需要注意一点,在一个struts.xml文件中,可能会有多个action标签,每个action标签中也可能会有多个result标签,那么该如何去表示这每一个标签呢?根据面向对象的编程方式:应该将每个action标签中的内容封装成一个ActionConfig对象,然后将每个action标签中的result标签也封装成一个ResultConfig对象,然后通过Map,将每个ResultConfig对象封装到它对应的ActionConfig对象中,然后将struts.xml中的每个ActionConfig对象也封装到一个Map,供我们使用。

ActionConfig类:

package com.hardstudy.entities;

import java.util.Map;

public class ActionConfig {
    private String name;
    private String clazz;
    private String method;
    private Map<String, ResultConfig> results;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getClazz() {
        return clazz;
    }
    public void setClazz(String clazz) {
        this.clazz = clazz;
    }
    public String getMethod() {
        return method;
    }
    public void setMethod(String method) {
        this.method = method;
    }
    public Map<String, ResultConfig> getResults() {
        return results;
    }
    public void setResults(Map<String, ResultConfig> results) {
        this.results = results;
    }

}

ResultConfig类:

package com.hardstudy.entities;

public class ResultConfig {
    private String name;
    private String target;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getTarget() {
        return target;
    }
    public void setTarget(String target) {
        this.target = target;
    }

}

一定要注意:这两个Map对象的key值都是使用ActionConfig对象的name以及ResultConfig的name来唯一标识的,同样的,只要解析获得了action标签中的name,那个就可以从Map对象中取到封装好了的对象。
**

7、最关键的一个文件:过滤器Filter:StrutsPrepareAndExecuteFilter,不要忘记在web.xml中配置这个过滤器,当然此处是不需要的,因为使用了注解:@WebFilter(“/*”),表示该过滤器作用于所有的请求

package com.hardstudy.filter;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.hardstudy.entities.ActionConfig;
import com.hardstudy.entities.ResultConfig;
import com.hardstudy.utils.ConfigManager;

@WebFilter("/*")
public class StrutsPreparedAndExcuteFilter implements Filter {
    Map<String, ActionConfig> configs = new HashMap<>();

    public void init(FilterConfig fConfig) throws ServletException {
        configs = ConfigManager.getActionConfig();
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        //获取路径:http://localhost:8080/struts_mini/HelloAction.action -->> /HelloAction.action
        String path = req.getServletPath();
        //先判断以下path,看看是不是Action发送的
        if(!path.endsWith(".action")){
            chain.doFilter(req, resp);
            return;
        }
        //将路径分解,得到   HelloAction
        //取左不取右
        path = path.substring(1,path.lastIndexOf("."));

        //得到了这个值之后,就可以让它去与struts.xml中的action的name进行匹配,得到那个唯一的action
        ActionConfig config = configs.get(path);

        //目前,已经得到了封装好了的name属性为HelloAction的action标签,现在要做的就是得到class和method
        String actionClass = config.getClazz();
        String method = config.getMethod();

        //生成HelloAction对应的那个类的对象
        try {
            Class<?> clazz = Class.forName(actionClass);
            Method me = clazz.getMethod(method, null);
            //方法调用之后得到了结果:success
            String result = (String)me.invoke(clazz.newInstance(), null);
            ResultConfig config2 = config.getResults().get(result);
            String target = config2.getTarget();
            req.getRequestDispatcher(target).forward(req, resp);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }

    public void destroy() {
    }
}


8、测试:在地址栏输入url:http://localhost:8080/struts_mini/HelloAction.action 经过一系列的操作步骤,最后成功到达index.jsp页面
这里写图片描述

index.jsp:
这里写图片描述
最后的结果:
这里写图片描述

这个项目的整体的流程图如下所示:
这里写图片描述

这是给自己看的,所以写的很渣,没啥料可言,就这样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值