汪志阳:
在request中方法的增强有三种方式:1.继承:需要控制方法所在类的构造;2.装饰柱模式:增强的类和被增强的类需要实现相同的接口,增强的类中获得被增强类的引用,缺点就是如果只要增强
其中的某个方法,其他方法也需要重写,为此我们引入了更加灵活的动态代理.动态代理抓哟是proxy对象该方法的使用
Proxy.newProxyInstance(ClassLoader cl,Class[] interfaces,InvocationHandler ih)
ClassLoader:类的加载器,通过调用类的getClassLoader进行获取;
Class[] interfaces:类中实现的接口的数组,通过类的getInterfaces方法获取;
最后的InvocationHandler,需要创建匿名内部类public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}我们增强的方法就是通过调用该匿名内部类实现的
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 判断执行的方法是否是getParameter,需要增强这个方法
if("getParameter".equals(method.getName())){
// 判断请求方式是GET还是POST:
String type = req.getMethod();
if("get".equalsIgnoreCase(type)){
String value = (String) method.invoke(req, args);
value = new String(value.getBytes("ISO-8859-1"),"UTF-8");
return value;
}else if("post".equalsIgnoreCase(type)){
req.setCharacterEncoding("UTF-8");
}
}
return method.invoke(req, args);
}
});
chain.doFilter(myReq, response);
}
这个动态代理,引入了新的思想面向切面,就是程序由jsp到servlet再到dao执行的顺序执行,我们在中间某一位置需要插入功能,切入的插入代码的思想.
编写一个BaseServlet:通用的servlet,主要是为了解决传统方试servlet创建过多带来的问题
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// 接收参数:http://localhost:8080/store_v2.0/UserSErvlet?method=regist
String methodName = req.getParameter("method");
if (methodName == null || "".equals(methodName)) {
resp.getWriter().println("获取的参数为null!!!");
return;
}
try {
// Class<? extends String> class2 = methodName.getClass();regist方法:
// public String regist(HttpServletRequest req,HttpServletResponse
// resp){
// return “/login.jsp”;}
// 继承的是String,获取当前子类对象
Class<? extends BaseServlet> clazz = this.getClass();
// 获取方法
Method method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
// 使用方法invoke(调用方法的对象,方法参数),返回路径"login.jsp"
String path = (String) method.invoke(this, req, resp);
if (path != null) {
req.getRequestDispatcher(path).forward(req, resp);
}
} catch (Exception e) {
e.printStackTrace();
}
这个通用的servlet主要运用反射机制,比较难理解的是代码中的两个this,这个servlet看成一个工具类,其他userServlet继承该类,this代表的就是继承该类的那个使用类,继承的类返回一个jsp的路径. |