1.规则匹配Mapping实现

【课前思考】

1.框架是如何根据用户的请求地址找到匹配的执行方法?

2.重构ActionMapper

由上一章可以看到,框架是通过actionMapping来知道用户请求所对应的处理类和处理方法,ActionMapper里的findMapping方法是通过硬编码方式直接返回了一个ActionMapping,但是现实中,框架不可能知道该请求对应的映射Mapping是什么的,那么框架是怎么根据uri就能找到对应的mapping呢?一般这些映射关系都是通过注解或者配置文件配置的,我们来改造findMapping方法,让它从配置类中获取请求相匹配的mapping而不是硬编码方式, 本章通过WebConfig类来模拟框架从配置文件加载所有映射文件。

【思路】

  1. 从请求实体中获取Uri
  2. 根据Uri地址截取用户请求的方法名
  3. 从配置文件获取所有规则匹配映射
  4. 根据请求方法名找到匹配的映射类
  5. 把通用Mapping转换成我们想要的ActionMapping

模块:

  1. WebConfig 用于管理配置文件,在本章负责加载所有规则匹配的映射配置

  2. Mapping 新创建的一个Mapping类,结构与ActionMapping相同,可以理解为是一个通用的Mapping类,最后会转化成对应的ActionMapping

2.1 改造前

上一章我们是通过硬编码方式获取ActionMapping

public class ActionMapper {

public ActionMapping findMapping(ServletRequest request) {

ActionMapping actionMapping = new ActionMapping();

actionMapping.setClassName("com.eshare.action.PersonAction");

actionMapping.setMethodName("hello");

return actionMapping;

}

}

2.2 改造后

【说明】

  1. 我们需要把request请求转换成httpServletRequst类型,实际上容器传给我们的request就是httpServletRequst类型
  2. 通过request实体,我们可以获取到这次请求的Uri,本章的Uri为/eshare/hello
  3. 我们要获取请求的方法名,需要从Uri截取,从Uri的格式可以知道,最后一个斜杠后的hello就是我们想要的方法名,而前面部分就是我们上下文路径,我们只需要把它截取即可
  4. 创建一个WebConfig类,用来管理所有映射配置的生命周期,从webConfig可以获取到所有的规则匹配配置mappings
  5. 然后从mappings中,根据方法名,找到相匹配的mapping,mapping存放的就是目标处理类的信息
  6. 最后把mapping转换成我们所需要的ActionMapping返回
public ActionMapping findMapping(ServletRequest request) {

ActionMapping actionMapping = new ActionMapping();

//把请求实体类型转换成HttpServletRequest

HttpServletRequest req = (HttpServletRequest) request;

//从请求实体中获取Uri

String uri = req.getRequestURI();

//根据Uri地址截取用户请求的方法名

String methodName = uri.substring(req.getContextPath().length()+1);

//从配置文件获取所有规则匹配映射

WebConfig webConfig = new WebConfig();

Map<String, Mapping> mappings = webConfig.getMappings();

//根据请求方法名找到匹配的映射类

Mapping mapping = mappings.get(methodName);

//把mapping转换成对应的actionMapping返回

actionMapping.setClassName(mapping.getClassName());

actionMapping.setMethodName(mapping.getMethodName());

actionMapping.setResult(mapping.getResult());

return actionMapping;

}

3.创建一个Mapping

【思路】

本章所用的Mapping结构跟ActionMapping一样,只是把里面的内容抽象出来,相当于所有Mapping的一个基类,便于框架处理使用,不需要每种类型的mapping都创建一个,执行完只需要转换成对应类型的mapping即可(如ActionMapping)。

public class Mapping {

/**

* 类全限定名

*/

private String className;

/**

* 方法名

*/

private String methodName;

/**

* 返回结果

*/

private String result;

public String getClassName() {

return className;

}

public void setClassName(String className) {

this.className = className;

}

public String getMethodName() {

return methodName;

}

public void setMethodName(String methodName) {

this.methodName = methodName;

}

public String getResult() {

return result;

}

public void setResult(String result) {

this.result = result;

}

}

4.创建一个WebConfig

WebConfig是用于管理所有规则映射mapping配置,在本章模拟WebConfig加载所有框规则映射文件,使得框架可以获取框架使用者自定义的所有映射配置,从而可以根据规则获取对应的mapping实例。

属性
1.mappings 存放所有mapping与其对应规则,便于框架可以根据规则来获取对应的mapping实例

public class WebConfig {

private Map<String,Mapping> mappings;

public WebConfig(){

//加载映射配置

loadMappingConfigs();

}

/**

* 加载映射配置

*/

public void loadMappingConfigs(){

mappings = new HashMap<String, Mapping>();

Mapping mapping = new Mapping();

//模拟框架扫描到所有框架使用者配置的映射配置

mapping.setClassName("com.eshare.action.PersonAction");

mapping.setMethodName("hello");

mapping.setResult("SUCCESS.jsp");

//模拟配置文件把规则匹配与映射类存放

mappings.put("hello",mapping);

}

public Map<String, Mapping> getMappings() {

return mappings;

}

public void setMappings(Map<String, Mapping> mappings) {

this.mappings = mappings;

}

}

5.修改测试类PersonAction

本章我们修改PersonAction中的hello方法输出内容,用来区分上一章的输出内容

public String hello(){

System.out.println("hello ch2");

boolean flag = false;

if(flag){

return "SUCCESS";

}else {

return "FAILE";

}

}

6.最终工程目录结构

在这里插入图片描述

7.测试规则匹配Mapping

7.1 启动tomcat

7.2 在浏览器输入URL

我的上下文路径是eshare

http://localhost:8080/eshare/hello

7.3 查看控制台输出结果

在这里插入图片描述

8.本章源码Github地址

Github:https://github.com/Evan43789596/FrameworkDesign.git

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐