JavaWeb无框架,借助反射采用精巧设计模式实现放微信PC聊天页面

本周开始在写仿写一个微信PC端的聊天页面,没有使用ssh、ssm等框架,采用JavaWeb、反射、MySQL、C3P0等技术。这里把其中和核心技术列出来请大家指教。

与传统JavaWeb项目的区别

传统的JavaWeb项目每一个请求都要写一个对应的Servlet,这样会造成一个工程完成下来需要写几十个Servlet,而利用反射原理(根据获取到的url-pattern,截取出相应的方法名,进而调用相应的方法)就可以很好的解决这个问题。

1、配置web.xml文件

利用中设置的值来进行分组,user请求都会调用UserServlet


  <servlet>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>com.hsy.action.UserServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/user</url-pattern>
  </servlet-mapping>

2、创建工具类BaseServlet

这个类是整个项目的技术核心,通过getParameter("method")与getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class)来决定将要访问的方法。通过Class c = this.getClass();来拿到调用当前方法的类,最后通过invoke(this, req, res)来执行对应的方法


public class BaseServlet extends HttpServlet {
	/*
	 * 它会根据请求中的m,来决定调用本类的哪个方法
	 */
	protected void service(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		res.setContentType("text/html;charset=utf-8");

		// 例如:http://localhost:8080/demo1/xxx?method=login
		String methodName = req.getParameter("method");// 它是一个方法名称

		// 当没用指定要调用的方法时,那么默认请求的是execute()方法。
		if(methodName == null || methodName.isEmpty()) {
			methodName = "execute";
		}
		Class c = this.getClass();
		try {
			// 通过方法名称获取方法的反射对象
			Method m = c.getMethod(methodName, HttpServletRequest.class,
					HttpServletResponse.class);
			// 反射方法目标方法,也就是说,如果methodName为add,那么就调用add方法。
			String result = (String) m.invoke(this, req, res);
			// 通过返回值完成请求转发
			if(result != null && !result.isEmpty()) {
				req.getRequestDispatcher(result).forward(req, res);
			}
		} catch (Exception e) {
			throw new ServletException(e);
		}
	}
}

3、创建UserServlet并继承工具类BaseServlet

这里只是简单的用这个例子来说明一个他的工作原理。假设一个请求http://localhost:8080/demo1/user?method=login过来了之后,首先会根据web.xml找到下面的UserServlet。猛的一看可能有点懵逼(这TM跑到这里就能执行login方法吗???这不是扯淡吗)。别急,听我慢慢道来。这个UserServlet继承了工具类BaseServlet,通过上一步的反射技术我们不就可执行本类中的login方法了吗?感觉有点不对劲?这就对了!!!我访问本类就算是继承了BaseServlet方法就能自动执行父类中的方法吗?一般情况下是不行的,就算是构造方法也要实例化子类时才能调用父类的构造方法啊。但这里是可以的,因为,在Servlet的生命周期方法中会自动调用server方法,也就是说会先调用本类的server方法、然后就会自动调用父类的server方法了。这样就实现了一个工具类BaseServlet共多个子类使用而调用不同的方法(现在很多框架的底层实现就是这样的)。


public class UserServlet extends BaseServlet {
    public String login(HttpServletRequest request,HttpServletResponse response){
        System.out.println("UserServlet中的login方法调用了");
        return null;
    }
}

posted @ 2019-08-11 15:07  岸北  阅读(311)  评论(0编辑  收藏  举报