提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
上次是通过过滤器的doFilter方法实现的,想想每次都要执行反射的内容,感觉,有点太占资源,就想到了,直接在过滤器的init方法,这样只会执行一次,然后将所有的servlet放到tomcat容器中就可以了。
当然步骤还是老样子
一、创建注解RequestMapping
代码如下(示例):
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
public String value();
}
- @Target:用来限制注解的使用范围;ElementType.TYPE是可以在类上使用;ElementType.METHOD是可以在方法上使用
- @Retention:是声明该注解是否被虚拟机读取,默认是不被读取的;RetentionPolicy.RUNTIME就可以让虚拟机读取
- @Documented:注解表明这个注解应该被 javadoc工具记录。默认情况下,javadoc是不包括注解的。
二、创建一个继承HttpServlet的类
代码如下(示例):
@RequestMapping("/ok")
public class TestController extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("Hello World");
writer.close();
}
@RequestMapping("/test")
public void test(HttpServletRequest request, HttpServletResponse response) {
PrintWriter writer;
try {
writer = response.getWriter();
writer.write("test");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
一个@RequestMapping在类上,另一个在方法上来模仿springMVC的@RequestMapping
三、创建过滤器
代码如下(示例):
@WebFilter("/*")
public class InitFilter implements Filter {
@Override
public void destroy() {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
ServletContext servletContext = filterConfig.getServletContext();
String realPath = servletContext.getRealPath("\\WEB-INF\\classes");
// servlet的目录
File file = new File(realPath + "\\com\\controller");
// 获取servlet目录下的所有类
String[] list = file.list();
for (String string : list) {
// 截取类名称
String name = string.substring(0, string.lastIndexOf("."));
try {
// 通过反射获取Class对象
Class c = Class.forName("com.controller." + name);
// 判断该类上是否有RequestMapping注解
String value = "";
if (c.isAnnotationPresent(RequestMapping.class)) {
// 获取注解,进行强制转换成RequestMapping对象
RequestMapping annotation = (RequestMapping)c.getAnnotation(RequestMapping.class);
// 获取RequestMapping对象的值
value += annotation.value();
}
// 获取所有的方法
// 没有就调用父类的service方法
Method[] methods = c.getDeclaredMethods();
// 循环遍历判断是否RequestMapping这个注解
for (Method method : methods) {
if(method.isAnnotationPresent(RequestMapping.class)) {
RequestMapping meRequestMapping = (RequestMapping)method.getAnnotation(RequestMapping.class);
String meValue = meRequestMapping.value();
// 创建继承HttpServlet的类
Object o = c.newInstance();
// 添加Servlet
Dynamic servlet = servletContext.addServlet(name, new HttpServlet() {
private Object object = o;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
method.invoke(object, req, resp);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
// 添加Servlet的映射地址
servlet.addMapping(value + meValue);
System.out.println(value + meValue);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
}
}
}
总结
优化这个需要深入理解tomcat的生命周期。我就一步步来,虽然不知道会优化到那种程度就放弃,但还是要坚持的。