jar包准备:servlet-api-3.0.jar
项目结构如下:

注解Mapping ,用于映射url地址

/** 文件名:Action.java* 版权:Copyright 2007-2016 517na Tech. Co. Ltd. All Rights Reserved. * 描述: Action.java* 修改人:peiyu* 修改时间:2016年7月29日* 修改内容:新增*/
package com.servlet3.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapping {String value();
}

ActionModel,用于封装Action信息

/** 文件名:ActionModel.java* 版权:Copyright 2007-2016 517na Tech. Co. Ltd. All Rights Reserved. * 描述: ActionModel.java* 修改人:peiyu* 修改时间:2016年8月1日* 修改内容:新增*/
package com.servlet3.util;import java.io.Serializable;
import java.lang.reflect.Method;/*** @author     peiyu*/
public class ActionModel implements Serializable{/*** 添加字段注释.*/private static final long serialVersionUID = 1L;private String className;private Method method;private Object action;/*** 设置className.* @return 返回className*/public String getClassName() {return className;}/*** 获取className.* @param className 要设置的className*/public void setClassName(String className) {this.className = className;}/*** 设置method.* @return 返回method*/public Method getMethod() {return method;}/*** 获取method.* @param method 要设置的method*/public void setMethod(Method method) {this.method = method;}/*** 设置action.* @return 返回action*/public Object getAction() {return action;}/*** 获取action.* @param action 要设置的action*/public void setAction(Object action) {this.action = action;}
}

MyFilter过滤器,初始化时创建扫描指定包下的所有类的注解,解析URL,创建Bean

/** 文件名:MyFilter.java* 版权:Copyright 2007-2016 517na Tech. Co. Ltd. All Rights Reserved. * 描述: MyFilter.java* 修改人:peiyu* 修改时间:2016年7月29日* 修改内容:新增*/
package com.servlet3.filter;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URLDecoder;
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 com.servlet3.annotation.Mapping;
import com.servlet3.exception.URLException;
import com.servlet3.util.ActionModel;
import com.servlet3.util.CommentedProperties;/*** * @author peiyu*/
@WebFilter(filterName = "MyFilter", urlPatterns = {"/*"})
public class MyFilter implements Filter {@Overridepublic void destroy() {System.out.println("-----------------------destroy-----------------------");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;String uri = httpServletRequest.getRequestURI();//访问的逻辑地址/myServlet3String url = uri.substring(uri.indexOf("/", 1));httpServletRequest.getRequestURL();System.out.println("-----------------------doFilter-----------------------");request.setAttribute("url", url);request.getRequestDispatcher("/myServlet3").forward(request,response);}/***1. 获取配置文件中配置的需扫描的包名*2. 根据包名扫描注解,获取URL,创建Bean实例*/@Overridepublic void init(FilterConfig config) throws ServletException {//获取配置文件中的包路径CommentedProperties properties = new CommentedProperties();//   /D:/software/apache-tomcat-7.0.59/webapps/Servlet3.0/WEB-INF/classes/scan-package.propertiesString classPath = MyFilter.class.getClassLoader().getResource("").getPath();String path = classPath + "scan-package.properties";System.out.println("####1加载配置文件:" + path);try {path = URLDecoder.decode(path, "UTF-8");} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}System.out.println("####2加载配置文件:" + path);try {properties.load(new FileInputStream(path), "UTF-8");} catch (IOException e) {e.printStackTrace();}//获取到包路径String scanPackage = properties.getProperty("scan-package").replace(".", "/");/*************************** 扫描包下的所有文件 ***************************************///获取到class文件路径path = classPath + scanPackage;Map<String, ActionModel> urls = new HashMap<>();File file = new File(path);//获取Action,url信息getFileUrls(file, urls);//将Action,url信息放到ServletContextconfig.getServletContext().setAttribute("urls", urls);}/*** 获取URL.*/private void getFileUrls(File file, Map<String, ActionModel> urls) {if (file.isDirectory()) { //如果是文件夹,获取文件夹下的文件File[] files = file.listFiles();for (File temp : files) {if (temp.isDirectory()) {getFileUrls(temp, urls);} else {getFileUrl(temp, urls);}}} else { //如果是文件getFileUrl(file, urls);}}/*** 获取URL,创建Action bean.*/@SuppressWarnings("rawtypes")private void getFileUrl(File temp, Map<String, ActionModel> urls) {String path;path = temp.getPath();String className = path.substring(path.indexOf("com"), path.lastIndexOf(".")).replace("\\", ".");try {Class clazz = Class.forName(className);//获取类注解String startUrl = "";//Annotation[] annotations = clazz.getAnnotations();//for (Annotation annotation : annotations) {//   if (annotation instanceof Mapping) { //判断是mapping//       startUrl = ((Mapping) annotation).value();//    }//}if (clazz.isAnnotationPresent(Mapping.class)) {startUrl = ((Mapping)clazz.getAnnotation(Mapping.class)).value();}//获取方法上注解Method[] methods = clazz.getMethods();Object action=clazz.newInstance();for (Method method : methods) {if (method.isAnnotationPresent(Mapping.class)) {ActionModel actionModel = new ActionModel();actionModel.setClassName(className);actionModel.setMethod(method);actionModel.setAction(action);Mapping annotation=method.getAnnotation(Mapping.class);String key = startUrl + ((Mapping) annotation).value();if (urls.containsKey(key)) {throw new URLException("已存在URL:" + key);} else {urls.put(key, actionModel);}}//annotations = method.getAnnotations();//for (Annotation annotation : annotations) {//    if (annotation instanceof Mapping) { //判断是mapping//        ActionModel actionModel=new ActionModel();//        actionModel.setClassName(className);//        actionModel.setMethod(method);//        actionModel.setAction(action);//        String key = startUrl + ((Mapping) annotation).value();//        if (urls.containsKey(key)) {//            throw new URLException("已存在URL:"+key);//        }else {//            urls.put(key, actionModel);//        }//    }//}}} catch (Exception e) {e.printStackTrace();}}
}

scan-package.properties配置需要扫描的包

scan-package=com.servlet3.controller

默认访问的Servlet,通过该Servlet找到指定的URL地址

/** 文件名:MyServlet3.java* 版权:Copyright 2007-2016 517na Tech. Co. Ltd. All Rights Reserved. * 描述: MyServlet3.java* 修改人:peiyu* 修改时间:2016年7月29日* 修改内容:新增*/
package com.servlet3.controller;import java.io.IOException;
import java.util.Map;import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.servlet3.util.ActionModel;/*** name:当前Servlet 的名称* urlPatterns:请求的url* loadOnStartup:tomcat启动时就初始化该servlet* initParams:初始化参数* name:参数名* value:参数值* * @author peiyu*/
@WebServlet(name = "MyServlet3",
urlPatterns = {"/myServlet3"},
loadOnStartup = 1,
initParams = {@WebInitParam(name = "name", value = "java"), @WebInitParam(name = "age", value = "1")})
public class MyServlet3 extends HttpServlet {/*** 添加字段注释.*/private static final long serialVersionUID = 1L;@SuppressWarnings({"unchecked"})@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String url=(String) req.getAttribute("url");Map<String, ActionModel> urls =(Map<String, ActionModel>) req.getServletContext().getAttribute("urls");ActionModel actionModel=urls.get(url);if (actionModel!=null) {try {Object res=actionModel.getMethod().invoke(actionModel.getAction(), req,resp);//根据返回的结果类型,返回值进行处理if (res instanceof String) {if (((String) res).startsWith("redirect:")) {//......}else if (((String) res).startsWith("forward:")) {//......}}else{//......}} catch (Exception e) {e.printStackTrace();}}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

测试的UserAction

/** 文件名:UserAction.java* 版权:Copyright 2007-2016 517na Tech. Co. Ltd. All Rights Reserved. * 描述: UserAction.java* 修改人:peiyu* 修改时间:2016年7月29日* 修改内容:新增*/
package com.servlet3.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.servlet3.annotation.Mapping;/*** @author     peiyu*/
@Mapping(value="/myServlet3")
public class UserAction {@Mapping(value="/login")public String login(HttpServletRequest req, HttpServletResponse resp){System.out.println("--------login-------------");return "redirect:register";}//register@Mapping(value="/register")public String register(HttpServletRequest req, HttpServletResponse resp){System.out.println("--------register-------------");return "redirect:login";}
}

最后,启动服务器,访问http://localhost:8072/Servlet3.0/myServlet3/login?name=java&age=1就会找到UserAction的login方法。

Servlet3.0实现的简单mvc框架相关推荐

  1. ajax注解解决中文乱码,基于注解的简单MVC框架的实现,以及jquery,prototype,ajax传输乱码问题的一点解决方法...

    1:基于注解的简单MVC框架的实现 效果:1:用户只需要定义一些普通的java类来做为M层,也就是STRUTS的action类,该类里包含1到 N个控制方法,每个方法需要的form数据,由注解@Act ...

  2. javafx 制作五子棋游戏——简单MVC框架

    目录 游戏描述 上手须知 源码地址 项目结构 一.实体层 二.视图层 三.控制器 四.测试 效果图 游戏描述 一个五子棋游戏,能实现双方黑白对决,当一方获胜时给出提示信息,利用Javafx实现GUI界 ...

  3. 源码分析系列 | 从零开始写MVC框架

    1. 前言 2. 为什么要自己手写框架 3. 简单MVC框架设计思路 4. 课程目标 5. 编码实战 5.1 配置阶段 web.xml配置 config.properties 自定义注解 5.2 初始 ...

  4. portlet_Spring Portlet MVC框架简介

    portlet 本文是由三部分组成的文章系列的第一篇文章,"开发供在IBM WebSphere Portal中使用的Spring Portlet MVC Framework应用程序" ...

  5. Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单。

    Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单. 前方: 开源地址:GitHub - cyq1162/Taurus.MVC: Taurus.mvc i ...

  6. 自己动手写一个简单的MVC框架(第二版)

    一.ASP.NET MVC核心机制回顾 在ASP.NET MVC中,最核心的当属"路由系统",而路由系统的核心则源于一个强大的System.Web.Routing.dll组件. 在 ...

  7. cocos2dx之lua项目开发中MVC框架的简单应用

    **************************************************************************** 时间:2015-03-31 作者:Sharin ...

  8. 【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目(5.5) 登录功能的实现,完善登录功能...

    索引 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目 目录索引 简述 今天我们来完善我们的登录功能 项目准备 我们用的工具是:VS 2013 + SqlServer 20 ...

  9. JAVA5000行代码什么概念_GitHub - catstiger/mvc: 一个不超过5000行代码的,快速,简单,易用的MVC框架。...

    一个不超过5000行代码的,快速,简单,易用的MVC框架. 我们的目的是: 让MVC回归其最初的目的. 因简单而快速,超过目前各种主流MVC. 零侵入,零配置,易于测试,并且让开发者感觉不到MVC的存 ...

最新文章

  1. java.util.ConcurrentModificationException异常原因及解决方法
  2. 产品经理对接第三方case,国内外4家公司联动落地项目
  3. python3多线程爬虫_【Python3 爬虫】U23_多线程爬虫之初识多线程
  4. 持续集成mysql_持续集成环境搭建(5)zabbix搭建和使用
  5. Java数组的十大方法
  6. Mac VSCode配置C语言环境(可以调试)
  7. 华南理工大学广州学院计算机二级,华南理工大学广州学院学子在第三届“泰迪杯”数据分析职业技能大赛中荣获佳绩...
  8. 五一小长假|不得不说的一些话
  9. [转]网友monkeylarry研究生期间我们应该做什么
  10. MATLAB语音识别系统[声纹识别]
  11. 解决微信、QQ在一加手机系统中无法限制后台的问题
  12. 项目启动阶段的主要工作
  13. 常用泰勒、微积分公式
  14. Android 旋转木马轮播,ReactJs写旋转木马轮播图
  15. java之STS使用和相关目录解说、springBoot微服务项目、前后端发送和接收参数的方式、文件图片视频上传
  16. linux识别riser卡,Riser卡和PCIe槽位
  17. 【T3】win10系统成功注册加密锁后,登录软件依然提示“产品未找到合法的license授权”
  18. ZOJ2477 拼魔方
  19. 一张图搞清楚矩阵 (性质解法归纳)
  20. 开源WordPress博客主题二次元风-LoliMeow主题

热门文章

  1. java代码实现九九乘法表
  2. 夜深人静写算法(三)- 初等数论入门
  3. Word模板文件,替换内容 文本、图片、表格、列表、区块、嵌套等
  4. python匹配ip地址
  5. 配置IPSAN得multipath服务,实现多路径
  6. 开发一个系统软件开发大概需要多少资金钱呢
  7. 【考生说】持之以恒才是胜利的推动器、一周时间通过C认证的同学怎么说
  8. 波形发生器设计(频率、占空比、幅值可调)
  9. mybatis ognl表达式
  10. FME+YOLOV7写DNF自动刷图脚本