关闭

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

标签: j2eejava webspringservlet框架
99人阅读 评论(0) 收藏 举报
分类:

通过上篇文章,我们已经对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、 路由、事件,队列、 缓存、日志等等,往后会逐步来实现这些功能。

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

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


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4105次
    • 积分:113
    • 等级:
    • 排名:千里之外
    • 原创:7篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论