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

来源:互联网 发布:苹果cms和海洋cms 编辑:程序博客网 时间:2024/06/06 00:36

通过上篇文章,我们已经对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 hereHttpServletRequest 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 chainchain.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 stubreturn null;}/** * @see Servlet#getServletInfo() */public String getServletInfo() {// TODO Auto-generated method stubreturn null;}/** * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse *      response) */protected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// TODO Auto-generated method stubString 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 stubresponse.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 stubdoGet(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
原创粉丝点击