在请求处理上具有责任链功能
存储拦截器类
package com.hole.servlet;
import com.hole.http.HttpSession;
import com.hole.util.Interceptor;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
/**
* @description: servlet 上下文
* @author: guozi
* @create: 2021-01-22
*/
public class ServletContext {
/**
* servlet容器,存储servlet
**/
public static Map<String, Object> servlets = new Hashtable<>();
/**
* session存储
**/
public static Map<String, HttpSession> sessionContext = new HashMap<>();
/**
* 拦截起类存储
**/
public static Map<String, String> interceptorContext = new HashMap<>();
}
拦截器接口
package com.hole.util;
import java.lang.reflect.Method;
/**
* @describtion: 拦截器接口
* @author: guozi
* @create: 2021-01-30
*/
public interface Interceptor {
/**
* @param proxy 代理对象
* @param target 目标对象
* @param method 目标方法
* @param args 方法参数
*/
boolean before(Object proxy, Object target, Method method, Object[] args);
void around(Object proxy, Object target, Method method, Object[] args);
void after(Object proxy, Object target, Method method, Object[] args);
}
拦截器父类
package com.hole.util;
import com.hole.server.DynamicProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
public class InterceptorObject implements Interceptor{
public static final Logger logger = LoggerFactory.getLogger(InterceptorObject.class);
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
logger.info("no before action to do");
return true;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
logger.info("no round action to do");
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
logger.info("no after action to do");
}
}
重点,利用反射和代理实现拦截器
package com.hole.util;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @describtion: 拦截器和真实对象代理代理
* @author: guozi
* @create: 2021-03-22
*/
public class InterceptorProxy implements InvocationHandler {
private Object target; //真实对象
private String interceptorClass = null;//拦截器全限定名
public InterceptorProxy(Object target, String interceptorClass) {
this.target = target;
this.interceptorClass = interceptorClass;
}
/**
* 绑定委托对象并返回一个【代理占位】
*
* @param target 真实对象
* @return 代理对象【占位】
*/
public static Object bind(Object target, String interceptorClass) {
//取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InterceptorProxy(target, interceptorClass));
}
@Override
/**
* 通过代理对象调用方法,首先进入这个方法.
*
* @param proxy --代理对象
* @param method --方法,被调用方法
* @param args -- 方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (interceptorClass == null) {
//没有设置拦截器则直接反射原有方法
return method.invoke(target, args);
}
Object result = null;
//通过反射生成拦截器
Interceptor interceptor =
(Interceptor) Class.forName(interceptorClass).newInstance();
//调用前置方法,是否要执行原有对象的target方法
if (interceptor.before(proxy, target, method, args)) {
//反射原有对象方法
result = method.invoke(target, args);
} else {//返回false执行around方法
interceptor.around(proxy, target, method, args);
}
//调用后置方法
interceptor.after(proxy, target, method, args);
return result;
}
}
最后,在处理请求前,安装顺序调用拦截器
package com.hole.server;
import com.hole.http.HttpServletRequest;
import com.hole.http.HttpServletResponse;
import com.hole.servlet.ServletContext;
import com.hole.util.InterceptorProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* @describtion: 客户端连接信息处理服务
* @author: guozi
* @create: 2021-01-25
*/
public class ServerService implements Runnable{
/**
* 连接客户端信息
*/
private Socket client;
public static final Logger logger = LoggerFactory.getLogger(ServerService.class);
public ServerService(Socket socket){
super();
this.client = socket;
}
@Override
public void run() {
InputStream input = null;
OutputStream output = null;
try{
input = this.client.getInputStream();
output = this.client.getOutputStream();
}catch (Exception e){
logger.error("客户端{}连接断开,原因:{}", this.client.getRemoteSocketAddress(), e.getMessage());
return;
}
//采用的是http协议,基于连接信息,创建http请求和响应对象
HttpServletRequest httpServletRequest = new HttpServletRequest(input);
HttpServletResponse httpServletResponse = new HttpServletResponse(httpServletRequest, output);
//判断是否是动态还是静态请求,动态请求包括.action->要给到的处理类
String url = httpServletRequest.getRequestUrl();
Processor processor = null;
if(url.contains(".action")){
processor = new DynamicProcessor();
}else{
processor = new StaticProcessor();
}
//servlet处理 , 链式步骤处理过来的请求
Processor interceptorProxy = processor;
for(String interceptor : ServletContext.interceptorContext.values()){
interceptorProxy = (Processor) InterceptorProxy.bind(interceptorProxy,interceptor);
}
interceptorProxy.process(httpServletRequest, httpServletResponse);
try{
//http是短连接,需要及时关闭
this.client.close();
}catch (Exception e){
logger.error("客户端{}连接断开失败,原因:{}", this.client.getRemoteSocketAddress(), e.getMessage());
}
}
}