构建自己的Java Web框架(四)之JAVA反射机制在框架中初步使用

原创 2016年08月28日 16:32:14

通过上篇文章,我们已经对Java反射机制有了方方面面的了解,接下来结合前面的几篇内容来进一步实现我们自己的框架。

打开Eclipse,创建一个动态的web工程,结构如下:



第一步:创建URLFilter

package com.demo.filter;

import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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;

/**
 * Servlet Filter implementation class URLFilter
 */
@WebFilter("/URLFilter")
public class URLFilter implements Filter {

	/**
	 * Default constructor.
	 */
	public URLFilter() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse rep = (HttpServletResponse) response;
		String realPath = req.getServletContext().getRealPath("/");
		String uri = req.getRequestURI();
		System.out.println("Filter uri=====" + uri);

		File file = new File(realPath + uri);
		if (!file.exists() && !file.isDirectory()) {
			String url = req.getRequestURL().toString();
			System.out.println("Filter url=====" + url);

			String rewriteUrl = "/index"; //默认入口
			rewriteUrl += "?" + uri.trim();
			System.out.println("Filter rewriteUrl=====" + rewriteUrl);

			String query = req.getQueryString();
			if (query != null) {
				query = query.toString();
				System.out.println("Filter query=====" + query);
				rewriteUrl += "?" + query;
			}
			System.out.println("Filter rewriteUrl=====" + rewriteUrl);

			if (null != rewriteUrl) {
				request.getRequestDispatcher(rewriteUrl).forward(req, rep);
				return;
			}
		}
		// pass the request along the filter chain
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

这个代码主要过滤所有的请求连接,如果请求的是资源文件等,则直接返回内容,如果不是则进入我们的默认入口(/index)servlet,对接下来的内容进行封装显示。


第二步:配置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>Demo</display-name>
  <welcome-file-list>
    <welcome-file>index</welcome-file>
    <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>
  <filter>
    <filter-name>urlFilter</filter-name>
    <filter-class>com.demo.filter.URLFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>urlFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

第三步:创建入口servlet

package com.demo.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class index
 */
@WebServlet("/index")
public class index extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public index() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Servlet#getServletConfig()
	 */
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @see Servlet#getServletInfo()
	 */
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		String className = "index";
		String methodName = "index";

		if (request.getQueryString() != null) {
			System.out.println("url ==== " + request.getRequestURL().toString());
			System.out.println("uri ==== " + request.getRequestURI());
			System.out.println("query ==== " + request.getQueryString().toString());

			String query = request.getQueryString().toString();
			String[] queryArr = query.split("\\?");
			System.out.println("router to ===" + queryArr[0]);

			String[] calssInfo = queryArr[0].trim().split("\\/");
			if (calssInfo.length > 1) {
				className = calssInfo[1].replaceAll("\\/", "").trim();
				// 首字母大写
				className = className.replaceFirst(className.substring(0, 1), className.substring(0, 1).toUpperCase());
				System.out.println("class===" + calssInfo[1]);
			}

			if (calssInfo.length > 2) {
				methodName = calssInfo[2].replaceAll("\\/", "").trim();
				System.out.println("action===" + methodName);
			}
		}

		try {
			Class<?> c = Class.forName("com.demo.contorller." + className);
			Class[] parameterTypes = { HttpServletRequest.class, HttpServletResponse.class };
			Constructor<?> constructor = c.getConstructor(parameterTypes);
			Object[] parameters = { request, response };
			Object obj = constructor.newInstance(parameters);
			Method method = c.getMethod(methodName + "Action", null);
			method.invoke(obj, null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
			// response.sendError(404);
			response.setStatus(404);
			PrintWriter out = response.getWriter();
			out.println("404 Page Not Found!");
		}
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

	/**
	 * @see HttpServlet#doPut(HttpServletRequest, HttpServletResponse)
	 */
	protected void doPut(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doDelete(HttpServletRequest, HttpServletResponse)
	 */
	protected void doDelete(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doHead(HttpServletRequest, HttpServletResponse)
	 */
	protected void doHead(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doOptions(HttpServletRequest, HttpServletResponse)
	 */
	protected void doOptions(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doTrace(HttpServletRequest, HttpServletResponse)
	 */
	protected void doTrace(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

}


这里是关键代码,用到了java的反射机制,并传了两个关键的对象:HttpServletRequest, HttpServletResponse

Class<?> c = Class.forName("com.demo.contorller." + className);
			Class[] parameterTypes = { HttpServletRequest.class, HttpServletResponse.class };
			Constructor<?> constructor = c.getConstructor(parameterTypes);
			Object[] parameters = { request, response };
			Object obj = constructor.newInstance(parameters);
			Method method = c.getMethod(methodName + "Action", null);
			method.invoke(obj, null);

如果类没有找到,我们就捕获异常,并返回404页面

response.setStatus(404);
			PrintWriter out = response.getWriter();
			out.println("404 Page Not Found!");




第四步:创建Contorller基类

package com.demo.contorller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Contorller {

	String output = "";
	public HttpServletRequest request;
	public HttpServletResponse response;

	public Contorller(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
	}

	public void load(String fileName) {
		String realPath = request.getServletContext().getRealPath("/");
		File file = new File(realPath + fileName);
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempString = "";
			while ((tempString = reader.readLine()) != null) {
				output += tempString + "\t\n";
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
			return;
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
	}

	public void display() throws IOException {
		PrintWriter out = response.getWriter();
		request.getServletContext();
		out.println(output);
		out.flush();
		out.close();
	}
}

第五步:实现我们自己的Contorller

package com.demo.contorller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Hello extends Contorller {

	public Hello(HttpServletRequest request, HttpServletResponse response) {
		super(request, response);
		// TODO Auto-generated constructor stub
	}

	public void indexAction() throws IOException
	{
		PrintWriter out = response.getWriter();
		out.println("This is index");
		out.flush();
		out.close();
	}
	
	public void worldAction() throws IOException
	{
		PrintWriter out = response.getWriter();
		out.println("Hello world!");
		out.flush();
		out.close();
		System.out.println("Hello world!");
	}
	
	public void homeAction() throws IOException
	{
		this.load("home.html");
		this.display();
	}
}

第六步:设置服务配置server.xml

主要是两个地方:一个端口号

<Connector connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443"/>
一个文件地址

<Context docBase="Demo" path="/" reloadable="true" source="org.eclipse.jst.jee.server:Demo"/>

启动服务,在浏览器中输入http://localhost/hello/world 或 http://127.0.0.1/hello/world

我也不例外的用了这个 hellow world,你懂得。


看到页面返回了“Hello world”,通过该链接,我们访问到了com.demo.contorller下面的Hello的worldAction方法

如果随便输入一个地址我们会看到如下页面:会看到404页面,因为在com.demo.contorller下面没有找到相关的类home,程序抛出了异常,并被捕获到了。


到这里,我们的框架已经有了一个雏形了,但他很简陋,还需要增加更多的功能,比如:依赖,容器、ORM、 路由、事件,队列、 缓存、日志等等,往后会逐步来实现这些功能。

如果你感觉本文对你有帮助,你可以继续关注我的博客,我会一步一步把框架实现。

这个路还很长很长,非常希望能和大家一起交流,共同学习和进步。
大家看过后觉得有启发的话可以顶一下这篇文章,让更多的朋友有机会看到它。也希望大家可以多留言来和我探讨框架相关的问题和知识。
最后,谢谢大家的支持!~~~


版权声明:本文为博主原创文章,未经博主允许不得转载。

构建自己的Java Web框架(三)之JAVA反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反...
  • ywch520
  • ywch520
  • 2016年06月28日 17:35
  • 351

java之反射机制

转载原文链接:http://www.jianshu.com/p/1a60d55a94cd今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来。那样太low了,今天跟我一起来...
  • whuhan2013
  • whuhan2013
  • 2016年05月10日 21:43
  • 1419

运行例子以后,能很好的理解spring的反射机制

此例子我已经运行过,运行再去看网上的那些关于java的反射机制,很更好的理解反射的作用. 以下部分为转载,很实用: 【转】java的反射和代理实现IOC模式 模拟spring 20...
  • zjhgx
  • zjhgx
  • 2013年02月26日 12:10
  • 5932

【框架基础】:Java反射机制详解(一)

在学习框架设计之前,先来了解一下框架基础——Java反射机制。         一、什么是反射机制         反射机制是在程序运行状态时,对于任意一个类,都能够知道这个类的所有属性和方法;对...
  • erlian1992
  • erlian1992
  • 2016年11月29日 15:13
  • 1353

Java反射在开发中的一些应用

有的时候,我们在开发的时候,由于要考虑到代码的重用性,自然而然的就会想到用反射来处理一些问题。 借用:java反射机制应用场景 一文 反射机制实现:  1)导出文件(1-4)  2)结果集在页面的显示...
  • xiaobangsky
  • xiaobangsky
  • 2014年01月07日 17:26
  • 3089

构建自己的Java Web框架(三)之JAVA反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反...
  • ywch520
  • ywch520
  • 2016年06月28日 17:35
  • 351

华为、阿里、京东使用的Java web框架是啥样的?

查看地址:https://niyao88.taobao.com/index.htm?        此java web框架是目前为止最完整、最强大、最时髦的框架,即使是华为、阿里巴巴、京东等也不例外...
  • software444
  • software444
  • 2015年11月08日 17:35
  • 4332

java web框架开发技术

  • 2014年10月19日 00:51
  • 28KB
  • 下载

搭建JAVA WEB框架

  • 2016年04月10日 15:35
  • 540KB
  • 下载

架构探险——从零开始写Java Web框架试读样章

  • 2015年11月09日 14:20
  • 771KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:构建自己的Java Web框架(四)之JAVA反射机制在框架中初步使用
举报原因:
原因补充:

(最多只允许输入30个字)