Browse Source

青涩知夏->优化网关

青涩知夏 4 years ago
parent
commit
6b110d6367
38 changed files with 775 additions and 154 deletions
  1. 5 0
      pom.xml
  2. 1 1
      src/main/java/cn/nosum/NoSumGateWayStart.java
  3. 9 0
      src/main/java/cn/nosum/common/constant/Constants.java
  4. 101 0
      src/main/java/cn/nosum/common/dto/ResultInfo.java
  5. 23 0
      src/main/java/cn/nosum/common/enums/ResultEnum.java
  6. 6 0
      src/main/java/cn/nosum/common/exception/BlockException.java
  7. 4 0
      src/main/java/cn/nosum/common/exception/ExcludeException.java
  8. 28 0
      src/main/java/cn/nosum/common/http/entity/Context.java
  9. 71 0
      src/main/java/cn/nosum/common/http/entity/Request.java
  10. 8 12
      src/main/java/cn/nosum/http/Response.java
  11. 18 0
      src/main/java/cn/nosum/common/http/factory/ContextFactory.java
  12. 17 0
      src/main/java/cn/nosum/common/http/servlet/AbsGateWayServlet.java
  13. 7 0
      src/main/java/cn/nosum/common/http/servlet/IGateWayServlet.java
  14. 20 0
      src/main/java/cn/nosum/common/http/servlet/factory/GateWayServletFactory.java
  15. 21 0
      src/main/java/cn/nosum/common/http/servlet/impl/GetGateWayServlet.java
  16. 21 0
      src/main/java/cn/nosum/common/http/servlet/impl/PostGateWayServlet.java
  17. 101 0
      src/main/java/cn/nosum/common/util/FastJsonUtils.java
  18. 21 0
      src/main/java/cn/nosum/gateway/chain/AbstractLinkedProcessorSlot.java
  19. 34 0
      src/main/java/cn/nosum/gateway/chain/DefaultProcessorSlotChain.java
  20. 14 0
      src/main/java/cn/nosum/gateway/chain/DefaultSlotChainBuilder.java
  21. 11 0
      src/main/java/cn/nosum/gateway/chain/ProcessorSlot.java
  22. 20 0
      src/main/java/cn/nosum/gateway/chain/ProcessorSlotChain.java
  23. 14 0
      src/main/java/cn/nosum/gateway/chain/SlotChainBuilder.java
  24. 18 0
      src/main/java/cn/nosum/gateway/chain/SlotChainProvider.java
  25. 14 10
      src/main/java/cn/nosum/container/NettyGatewayContainer.java
  26. 23 0
      src/main/java/cn/nosum/gateway/handler/FinalProcessHandler.java
  27. 23 0
      src/main/java/cn/nosum/gateway/handler/FullHttpRequestHandler.java
  28. 18 0
      src/main/java/cn/nosum/gateway/handler/PreProcessHandler.java
  29. 37 0
      src/main/java/cn/nosum/gateway/handler/SlotProcessHandler.java
  30. 14 0
      src/main/java/cn/nosum/gateway/slot/FileProcessorSlotChain.java
  31. 18 0
      src/main/java/cn/nosum/gateway/slot/LogProcessorSlotChain.java
  32. 19 0
      src/main/java/cn/nosum/gateway/slot/UrlProcessorSlotChain.java
  33. 0 27
      src/main/java/cn/nosum/handler/GateWayHandler.java
  34. 0 30
      src/main/java/cn/nosum/handler/HttpRequestHandler.java
  35. 0 7
      src/main/java/cn/nosum/handler/spi/IRequestHandler.java
  36. 0 48
      src/main/java/cn/nosum/http/Request.java
  37. 0 19
      src/main/java/cn/nosum/http/Servlet.java
  38. 16 0
      src/main/resources/log4j.properties

+ 5 - 0
pom.xml

@@ -26,6 +26,11 @@
             <artifactId>fastjson</artifactId>
             <version>1.2.4</version>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.25</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 1 - 1
src/main/java/cn/nosum/NoSumGateWayStart.java

@@ -1,6 +1,6 @@
 package cn.nosum;
 
-import cn.nosum.container.NettyGatewayContainer;
+import cn.nosum.gateway.container.NettyGatewayContainer;
 
 public class NoSumGateWayStart {
     public static void main(String[] args) {

+ 9 - 0
src/main/java/cn/nosum/common/constant/Constants.java

@@ -0,0 +1,9 @@
+package cn.nosum.common.constant;
+
+public class Constants {
+    public final static String ICON_URL="/favicon.ico";
+    public final static String REQUEST_METHOD_POST="POST";
+    public final static String REQUEST_METHOD_GET="GET";
+    public final static String REQUEST_METHOD_DELETE="DELETE";
+    public final static String REQUEST_METHOD_PUT="PUT";
+}

+ 101 - 0
src/main/java/cn/nosum/common/dto/ResultInfo.java

@@ -0,0 +1,101 @@
+package cn.nosum.common.dto;
+
+import cn.nosum.common.enums.ResultEnum;
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.Serializable;
+
+public class ResultInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+	/**
+     * 结果码
+     */
+	private int code;
+
+	/**
+     * 结果详情
+     */
+	private String msg;
+
+	/**
+	 * 具体接口的业务返回信息,由具体接口义务定义 返回的结果包装在data中,data可以是单个对象
+	 */
+	private Object data;
+	
+	
+	/**
+	 * error: 错误信息类型,JOSN对象,如果发生异常,这里放的是异常信息, errorCode:错误编码 errorSn:错误编号
+	 * errorMsg:错误信息 errorCause:错误信息 errorAction:错误接口名
+	 */
+	private JSONObject error;
+
+
+	public int getCode() {
+		return code;
+	}
+
+	public void setCode(int code) {
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	public Object getData() {
+		return data;
+	}
+
+	public void setData(Object data) {
+		this.data = data;
+	}
+
+
+
+	public JSONObject getError() {
+		return error;
+	}
+
+	public void setError(JSONObject error) {
+		this.error = error;
+	}
+
+	public ResultInfo() {
+
+	}
+	
+	public ResultInfo(int code, String msg, Object data) {
+		this.code = code;
+		this.msg = msg;
+		this.data = data;
+	}
+	public ResultInfo(int code, String msg) {
+		this.code = code;
+		this.msg = msg;
+	}
+
+	public ResultInfo(Object data) {
+		this.code = ResultEnum.SUCCESS.getCode();
+		this.msg = ResultEnum.SUCCESS.getMsg();
+		this.data = data;
+	}
+	 
+	public static ResultInfo valueOf(Object data) {
+		return new ResultInfo(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg(), data);
+	}
+	public static ResultInfo valueOf(ResultEnum resultEnum) {
+		return new ResultInfo(resultEnum.getCode(), resultEnum.getMsg());
+	}
+
+	@Override
+    public String toString() {
+        return "ResultInfo [code=" + code
+        		+ ", msg=" + msg
+        		+ ", data=" + data;
+    }
+}

+ 23 - 0
src/main/java/cn/nosum/common/enums/ResultEnum.java

@@ -0,0 +1,23 @@
+package cn.nosum.common.enums;
+
+public enum ResultEnum {
+    SUCCESS(1, "成功"),
+    FAILING(0, "失败"),
+    URL_EXCLUDE(2,"无效的URL")
+    ;
+    private int code;
+    private String msg;
+
+    ResultEnum(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+}

+ 6 - 0
src/main/java/cn/nosum/common/exception/BlockException.java

@@ -0,0 +1,6 @@
+package cn.nosum.common.exception;
+
+
+public class BlockException extends Exception {
+    // TODO
+}

+ 4 - 0
src/main/java/cn/nosum/common/exception/ExcludeException.java

@@ -0,0 +1,4 @@
+package cn.nosum.common.exception;
+
+public class ExcludeException extends Exception {
+}

+ 28 - 0
src/main/java/cn/nosum/common/http/entity/Context.java

@@ -0,0 +1,28 @@
+package cn.nosum.common.http.entity;
+
+
+public class Context {
+    private Request request;
+    private Response response;
+
+    public Context(Request request, Response response) {
+        this.request = request;
+        this.response = response;
+    }
+
+    public Request getRequest() {
+        return request;
+    }
+
+    public void setRequest(Request request) {
+        this.request = request;
+    }
+
+    public Response getResponse() {
+        return response;
+    }
+
+    public void setResponse(Response response) {
+        this.response = response;
+    }
+}

+ 71 - 0
src/main/java/cn/nosum/common/http/entity/Request.java

@@ -0,0 +1,71 @@
+package cn.nosum.common.http.entity;
+
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.HttpRequest;
+import io.netty.handler.codec.http.QueryStringDecoder;
+import io.netty.handler.codec.http.multipart.Attribute;
+import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
+import io.netty.handler.codec.http.multipart.InterfaceHttpData;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Request {
+
+    private FullHttpRequest req;
+
+    private Map<String, String> paramMap;
+
+    public Request(FullHttpRequest req) {
+        this.req = req;
+        initParam(req);
+    }
+
+    private void initParam(FullHttpRequest req){
+        try{
+            HttpMethod method = req.method();
+            paramMap=new HashMap<>();
+            if (HttpMethod.GET == method) {
+                // GET请求
+                QueryStringDecoder decoder = new QueryStringDecoder(req.uri());
+                decoder.parameters().forEach((key, value) -> {
+                    // entry.getValue()是一个List, 只取第一个元素
+                    paramMap.put(key, value.get(0));
+                });
+            } else if (HttpMethod.POST == method) {
+                // POST请求
+                HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(req);
+                decoder.offer(req);
+                List<InterfaceHttpData> paramList = decoder.getBodyHttpDatas();
+                for (InterfaceHttpData param : paramList) {
+                    Attribute data = (Attribute) param;
+                    paramMap.put(data.getName(), data.getValue());
+                }
+            }
+        }catch (IOException e){
+            e.printStackTrace();
+        }
+    }
+
+    public String getUrl() {
+        return req.uri();
+    }
+
+    public String getMethod() {
+        return req.method().name();
+    }
+
+    public Map<String, String> getParameters() {
+        return paramMap;
+    }
+
+    public String getParameter(String name) {
+        return paramMap.get(name);
+    }
+}

+ 8 - 12
src/main/java/cn/nosum/http/Response.java

@@ -1,29 +1,25 @@
-package cn.nosum.http;
+package cn.nosum.common.http.entity;
 
-import com.alibaba.fastjson.JSONObject;
+import cn.nosum.common.dto.ResultInfo;
+import com.alibaba.fastjson.JSON;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.http.*;
-
 import java.nio.charset.StandardCharsets;
 
 
 public class Response {
 
-    // SocketChannel的封装
     private ChannelHandlerContext ctx;
 
-    private HttpRequest req;
-
-    public Response(ChannelHandlerContext ctx, HttpRequest req) {
+    public Response(ChannelHandlerContext ctx) {
         this.ctx = ctx;
-        this.req = req;
     }
 
-    public void write(JSONObject out) throws Exception {
+    public void write(ResultInfo resultInfo) throws Exception {
         try {
-            if (out == null) {
-                return;
+            if (resultInfo == null) {
+                return ;
             }
             // 设置 http协议及请求头信息
             FullHttpResponse response = new DefaultFullHttpResponse(
@@ -32,7 +28,7 @@ public class Response {
                     // 设置响应状态码
                     HttpResponseStatus.OK,
                     // 将输出值写出 编码为UTF-8
-                    Unpooled.wrappedBuffer(out.toJSONString().getBytes(StandardCharsets.UTF_8)));
+                    Unpooled.wrappedBuffer(JSON.toJSONString(resultInfo).getBytes(StandardCharsets.UTF_8)));
             response.headers().set("Content-Type", "application/json;");
             ctx.writeAndFlush(response);
         } finally {

+ 18 - 0
src/main/java/cn/nosum/common/http/factory/ContextFactory.java

@@ -0,0 +1,18 @@
+package cn.nosum.common.http.factory;
+
+
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.common.http.entity.Request;
+import cn.nosum.common.http.entity.Response;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.FullHttpRequest;
+
+public class ContextFactory {
+    private ContextFactory(){}
+    public static Context build(ChannelHandlerContext ctx, FullHttpRequest request){
+        if(request!=null){
+            return new Context(new Request(request),new Response(ctx));
+        }
+        return null;
+    }
+}

+ 17 - 0
src/main/java/cn/nosum/common/http/servlet/AbsGateWayServlet.java

@@ -0,0 +1,17 @@
+package cn.nosum.common.http.servlet;
+
+import cn.nosum.common.http.entity.Context;
+
+public abstract class AbsGateWayServlet implements IGateWayServlet{
+
+    @Override
+    public void service(Context context) {
+        if (this.doCheck(context)){
+            this.doService(context);
+        }
+    }
+
+    protected abstract void doService(Context context);
+
+    protected abstract boolean doCheck(Context context);
+}

+ 7 - 0
src/main/java/cn/nosum/common/http/servlet/IGateWayServlet.java

@@ -0,0 +1,7 @@
+package cn.nosum.common.http.servlet;
+
+import cn.nosum.common.http.entity.Context;
+
+public interface IGateWayServlet {
+    void service(Context context);
+}

+ 20 - 0
src/main/java/cn/nosum/common/http/servlet/factory/GateWayServletFactory.java

@@ -0,0 +1,20 @@
+package cn.nosum.common.http.servlet.factory;
+
+import cn.nosum.common.http.servlet.IGateWayServlet;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Servlet工厂,根据不同的请求类型调用不同的处理类
+ */
+public class GateWayServletFactory {
+    private static  Map<String, IGateWayServlet> gateWayServletMap = new ConcurrentHashMap<>();
+
+    public static IGateWayServlet getGateWayServlet(String method){
+        return gateWayServletMap.get(method);
+    }
+    public static void register(String method,IGateWayServlet gateWayServlet){
+        gateWayServletMap.put(method,gateWayServlet);
+    }
+}

+ 21 - 0
src/main/java/cn/nosum/common/http/servlet/impl/GetGateWayServlet.java

@@ -0,0 +1,21 @@
+package cn.nosum.common.http.servlet.impl;
+
+import cn.nosum.common.constant.Constants;
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.common.http.servlet.AbsGateWayServlet;
+
+public class GetGateWayServlet extends AbsGateWayServlet {
+
+    @Override
+    protected void doService(Context context) {
+
+    }
+
+    @Override
+    protected boolean doCheck(Context context) {
+        if (context!=null){
+            return Constants.REQUEST_METHOD_GET.equalsIgnoreCase(context.getRequest().getMethod());
+        }
+        return false;
+    }
+}

+ 21 - 0
src/main/java/cn/nosum/common/http/servlet/impl/PostGateWayServlet.java

@@ -0,0 +1,21 @@
+package cn.nosum.common.http.servlet.impl;
+
+import cn.nosum.common.constant.Constants;
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.common.http.servlet.AbsGateWayServlet;
+
+public class PostGateWayServlet extends AbsGateWayServlet {
+
+    @Override
+    protected void doService(Context context) {
+
+    }
+
+    @Override
+    protected boolean doCheck(Context context) {
+        if (context!=null){
+            return Constants.REQUEST_METHOD_POST.equalsIgnoreCase(context.getRequest().getMethod());
+        }
+        return false;
+    }
+}

+ 101 - 0
src/main/java/cn/nosum/common/util/FastJsonUtils.java

@@ -0,0 +1,101 @@
+package cn.nosum.common.util;
+
+import java.util.List;
+import java.util.Map;
+ 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.JSONLibDataFormatSerializer;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+ 
+/**
+ * fastjson工具类
+ */
+public class FastJsonUtils {
+ 
+    private static final SerializeConfig config;
+ 
+    static {
+        config = new SerializeConfig();
+        config.put(java.util.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib兼容的日期输出格式
+        config.put(java.sql.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib兼容的日期输出格式
+    }
+ 
+    private static final SerializerFeature[] features = {SerializerFeature.WriteMapNullValue, // 输出空置字段
+            SerializerFeature.WriteNullListAsEmpty, // list字段如果为null,输出为[],而不是null
+            SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null,输出为0,而不是null
+            SerializerFeature.WriteNullBooleanAsFalse, // Boolean字段如果为null,输出为false,而不是null
+            SerializerFeature.WriteNullStringAsEmpty // 字符类型字段如果为null,输出为"",而不是null
+    };
+    
+ 
+    public static String convertObjectToJSON(Object object) {
+        return JSON.toJSONString(object, config, features);
+    }
+    
+    public static String toJSONNoFeatures(Object object) {
+        return JSON.toJSONString(object, config);
+    }
+    
+ 
+ 
+    public static Object toBean(String text) {
+        return JSON.parse(text);
+    }
+ 
+    public static <T> T toBean(String text, Class<T> clazz) {
+        return JSON.parseObject(text, clazz);
+    }
+ 
+    /**
+     *  转换为数组
+     */
+    public static <T> Object[] toArray(String text) {
+        return toArray(text, null);
+    }
+ 
+    /**
+     *  转换为数组
+     */
+    public static <T> Object[] toArray(String text, Class<T> clazz) {
+        return JSON.parseArray(text, clazz).toArray();
+    }
+ 
+    /**
+     * 转换为List
+     */
+    public static <T> List<T> toList(String text, Class<T> clazz) {
+        return JSON.parseArray(text, clazz);
+    }
+ 
+    /**
+     * 将string转化为序列化的json字符串
+     */
+    public static Object textToJson(String text) {
+        return JSON.parse(text);
+    }
+    
+    /**
+     * json字符串转化为map
+     */
+    public static <K, V> Map<K, V>  stringToCollect(String s) {
+        Map<K, V> m = (Map<K, V>) JSONObject.parseObject(s);
+        return m;
+    }
+    
+    /**
+     * 转换JSON字符串为对象
+     */
+    public static Object convertJsonToObject(String jsonData, Class<?> clazz) {
+        return JSONObject.parseObject(jsonData, clazz);
+    }
+
+    /**
+     * 将map转化为string
+     */
+    public static <K, V> String collectToString(Map<K, V> m) {
+        String s = JSONObject.toJSONString(m);
+        return s;
+    }
+}

+ 21 - 0
src/main/java/cn/nosum/gateway/chain/AbstractLinkedProcessorSlot.java

@@ -0,0 +1,21 @@
+package cn.nosum.gateway.chain;
+
+public abstract class AbstractLinkedProcessorSlot<T> implements ProcessorSlot<T> {
+
+    private AbstractLinkedProcessorSlot<T> next = null;
+
+    public void fireExec(T t) throws Throwable {
+        if (next != null) {
+            next.exec(t);
+        }
+    }
+
+    public AbstractLinkedProcessorSlot<T> getNext() {
+        return next;
+    }
+
+    public void setNext(AbstractLinkedProcessorSlot<T> next) {
+        this.next = next;
+    }
+
+}

+ 34 - 0
src/main/java/cn/nosum/gateway/chain/DefaultProcessorSlotChain.java

@@ -0,0 +1,34 @@
+package cn.nosum.gateway.chain;
+
+import cn.nosum.common.http.entity.Context;
+
+public class DefaultProcessorSlotChain extends ProcessorSlotChain {
+
+    AbstractLinkedProcessorSlot<Context> first = new AbstractLinkedProcessorSlot<Context>() {
+        @Override
+        public void exec(Context context) throws Throwable {
+            this.fireExec(context);
+        }
+    };
+    AbstractLinkedProcessorSlot<Context> end = first;
+
+    @Override
+    public void addFirst(AbstractLinkedProcessorSlot<Context> protocolProcessor) {
+        protocolProcessor.setNext(first.getNext());
+        first.setNext(protocolProcessor);
+        if (end == first) {
+            end = protocolProcessor;
+        }
+    }
+
+    @Override
+    public void addLast(AbstractLinkedProcessorSlot<Context> protocolProcessor) {
+        end.setNext(protocolProcessor);
+        end = protocolProcessor;
+    }
+
+    @Override
+    public void exec(Context context) throws Throwable {
+        first.exec(context);
+    }
+}

+ 14 - 0
src/main/java/cn/nosum/gateway/chain/DefaultSlotChainBuilder.java

@@ -0,0 +1,14 @@
+package cn.nosum.gateway.chain;
+
+import cn.nosum.gateway.slot.LogProcessorSlotChain;
+import cn.nosum.gateway.slot.UrlProcessorSlotChain;
+
+public class DefaultSlotChainBuilder implements SlotChainBuilder {
+    @Override
+    public ProcessorSlotChain build() {
+        ProcessorSlotChain chain = new DefaultProcessorSlotChain();
+        chain.addLast(new UrlProcessorSlotChain());
+        chain.addLast(new LogProcessorSlotChain());
+        return chain;
+    }
+}

+ 11 - 0
src/main/java/cn/nosum/gateway/chain/ProcessorSlot.java

@@ -0,0 +1,11 @@
+package cn.nosum.gateway.chain;
+
+
+/**
+ * 处理槽链顶层接口,参考 sentinel
+ */
+public interface ProcessorSlot<T> {
+
+    void exec(T t) throws Throwable;
+
+}

+ 20 - 0
src/main/java/cn/nosum/gateway/chain/ProcessorSlotChain.java

@@ -0,0 +1,20 @@
+package cn.nosum.gateway.chain;
+
+import cn.nosum.common.http.entity.Context;
+
+public abstract class ProcessorSlotChain extends AbstractLinkedProcessorSlot<Context> {
+
+    /**
+     * Add a processor to the head of this slot chain.
+     *
+     * @param protocolProcessor processor to be added.
+     */
+    public abstract void addFirst(AbstractLinkedProcessorSlot<Context> protocolProcessor);
+
+    /**
+     * Add a processor to the tail of this slot chain.
+     *
+     * @param protocolProcessor processor to be added.
+     */
+    public abstract void addLast(AbstractLinkedProcessorSlot<Context> protocolProcessor);
+}

+ 14 - 0
src/main/java/cn/nosum/gateway/chain/SlotChainBuilder.java

@@ -0,0 +1,14 @@
+package cn.nosum.gateway.chain;
+
+
+/**
+ * 处理槽构建器顶层接口
+ */
+public interface SlotChainBuilder {
+
+    /**
+     * 构建处理槽链
+     * @return 返回构建完成的处理槽链
+     */
+    ProcessorSlotChain build();
+}

+ 18 - 0
src/main/java/cn/nosum/gateway/chain/SlotChainProvider.java

@@ -0,0 +1,18 @@
+package cn.nosum.gateway.chain;
+
+
+public final class SlotChainProvider {
+    private SlotChainProvider() {}
+    private static volatile SlotChainBuilder builder = null;
+
+    public static ProcessorSlotChain newSlotChain() {
+        if (builder != null) {
+            return builder.build();
+        }
+        // TODO 使用 SPI 与静态扩展点优化
+        if (builder == null) {
+            builder = new DefaultSlotChainBuilder();
+        }
+        return builder.build();
+    }
+}

+ 14 - 10
src/main/java/cn/nosum/container/NettyGatewayContainer.java

@@ -1,12 +1,15 @@
-package cn.nosum.container;
+package cn.nosum.gateway.container;
 
-import cn.nosum.handler.GateWayHandler;
-import cn.nosum.handler.HttpRequestHandler;
+import cn.nosum.gateway.handler.FinalProcessHandler;
+import cn.nosum.gateway.handler.FullHttpRequestHandler;
+import cn.nosum.gateway.handler.PreProcessHandler;
+import cn.nosum.gateway.handler.SlotProcessHandler;
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.*;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.http.HttpObjectAggregator;
 import io.netty.handler.codec.http.HttpRequestDecoder;
 import io.netty.handler.codec.http.HttpResponseEncoder;
 
@@ -16,9 +19,9 @@ public class NettyGatewayContainer {
 	private int port = 8888;
 	public void start(){
 		// Boss线程
-		EventLoopGroup bossGroup = new NioEventLoopGroup();
+		EventLoopGroup bossGroup = new NioEventLoopGroup(6);
 		// Worker线程
-		EventLoopGroup workerGroup = new NioEventLoopGroup();
+		EventLoopGroup workerGroup = new NioEventLoopGroup(12);
 		try {
 			ServerBootstrap server = new ServerBootstrap();
 			server.group(bossGroup, workerGroup)
@@ -28,13 +31,14 @@ public class NettyGatewayContainer {
 						// 客户端初始化处理
 						protected void initChannel(SocketChannel client) throws Exception {
 							// Netty对HTTP协议的封装,顺序有要求
-							// HttpResponseEncoder 编码器
-							client.pipeline().addLast(new HttpResponseEncoder());
-							// HttpRequestDecoder 解码器
 							client.pipeline().addLast(new HttpRequestDecoder());
+							client.pipeline().addLast(new HttpObjectAggregator(65535));//将多个消息转化成一个
+							client.pipeline().addLast(new HttpResponseEncoder());
+							client.pipeline().addLast(new FullHttpRequestHandler());
 							// 业务逻辑处理
-							client.pipeline().addLast(new HttpRequestHandler());
-							client.pipeline().addLast(new GateWayHandler());
+							client.pipeline().addLast(new SlotProcessHandler());
+							client.pipeline().addLast(new PreProcessHandler());
+							client.pipeline().addLast(new FinalProcessHandler());
 						}
 					})
 					// 针对主线程的配置 分配线程最大数量 128

+ 23 - 0
src/main/java/cn/nosum/gateway/handler/FinalProcessHandler.java

@@ -0,0 +1,23 @@
+package cn.nosum.gateway.handler;
+
+import cn.nosum.common.dto.ResultInfo;
+import cn.nosum.common.enums.ResultEnum;
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.common.http.entity.Response;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+public class FinalProcessHandler extends SimpleChannelInboundHandler<Context> {
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, Context context) throws Exception {
+        Response response = context.getResponse();
+        // 实际业务处理
+        response.write(ResultInfo.valueOf(ResultEnum.SUCCESS));
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+		ctx.close();
+    }
+}

+ 23 - 0
src/main/java/cn/nosum/gateway/handler/FullHttpRequestHandler.java

@@ -0,0 +1,23 @@
+package cn.nosum.gateway.handler;
+
+
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.common.http.factory.ContextFactory;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.codec.http.FullHttpRequest;
+
+public class FullHttpRequestHandler  extends SimpleChannelInboundHandler<FullHttpRequest> {
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
+        // 构建上下文对象
+        Context context= ContextFactory.build(ctx,req);
+        ctx.fireChannelRead(context);
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        ctx.close();
+    }
+}

+ 18 - 0
src/main/java/cn/nosum/gateway/handler/PreProcessHandler.java

@@ -0,0 +1,18 @@
+package cn.nosum.gateway.handler;
+
+import cn.nosum.common.http.entity.Context;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+public class PreProcessHandler extends SimpleChannelInboundHandler<Context>{
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, Context context) throws Exception {
+        ctx.fireChannelRead(context);
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        ctx.close();
+    }
+}

+ 37 - 0
src/main/java/cn/nosum/gateway/handler/SlotProcessHandler.java

@@ -0,0 +1,37 @@
+package cn.nosum.gateway.handler;
+
+import cn.nosum.common.dto.ResultInfo;
+import cn.nosum.common.enums.ResultEnum;
+import cn.nosum.common.exception.ExcludeException;
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.gateway.chain.ProcessorSlot;
+import cn.nosum.gateway.chain.SlotChainProvider;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+/**
+ * 执行处理槽链
+ */
+public class SlotProcessHandler extends SimpleChannelInboundHandler<Context> {
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, Context context) throws Exception {
+        // TODO 进行过滤链的执行
+        ProcessorSlot<Context> chain = SlotChainProvider.newSlotChain();
+        try {
+            chain.exec(context);
+            // 传递上下文对象到下一个 handler
+            ctx.fireChannelRead(context);
+        } catch (ExcludeException e) {
+            context.getResponse().write(ResultInfo.valueOf(ResultEnum.URL_EXCLUDE));
+        } catch (Throwable throwable) {
+            throwable.printStackTrace();
+            context.getResponse().write(ResultInfo.valueOf(ResultEnum.FAILING));
+        }
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        ctx.close();
+    }
+}

+ 14 - 0
src/main/java/cn/nosum/gateway/slot/FileProcessorSlotChain.java

@@ -0,0 +1,14 @@
+package cn.nosum.gateway.slot;
+
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.gateway.chain.AbstractLinkedProcessorSlot;
+
+/**
+ * 创建文件,进行IO操作
+ */
+public class FileProcessorSlotChain extends AbstractLinkedProcessorSlot<Context> {
+    @Override
+    public void exec(Context context) throws Throwable {
+        fireExec(context);
+    }
+}

+ 18 - 0
src/main/java/cn/nosum/gateway/slot/LogProcessorSlotChain.java

@@ -0,0 +1,18 @@
+package cn.nosum.gateway.slot;
+
+import cn.nosum.common.http.entity.Context;
+import cn.nosum.gateway.chain.AbstractLinkedProcessorSlot;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LogProcessorSlotChain extends AbstractLinkedProcessorSlot<Context> {
+
+    private static final Logger logger = LoggerFactory.getLogger(LogProcessorSlotChain.class);
+
+    @Override
+    public void exec(Context context) throws Throwable {
+        // TODO 日志记录
+        logger.debug(context.getRequest().getUrl());
+        fireExec(context);
+    }
+}

+ 19 - 0
src/main/java/cn/nosum/gateway/slot/UrlProcessorSlotChain.java

@@ -0,0 +1,19 @@
+package cn.nosum.gateway.slot;
+
+import cn.nosum.common.exception.ExcludeException;
+import cn.nosum.gateway.chain.AbstractLinkedProcessorSlot;
+import cn.nosum.common.constant.Constants;
+import cn.nosum.common.http.entity.Context;
+
+public class UrlProcessorSlotChain extends AbstractLinkedProcessorSlot<Context> {
+    @Override
+    public void exec(Context context) throws Throwable {
+        String uri=context.getRequest().getUrl();
+        // 过滤掉请求图标的地址
+        if (uri.equals(Constants.ICON_URL)) {
+            throw new ExcludeException();
+        }
+        // 执行下一个过滤器
+        fireExec(context);
+    }
+}

+ 0 - 27
src/main/java/cn/nosum/handler/GateWayHandler.java

@@ -1,27 +0,0 @@
-package cn.nosum.handler;
-
-import cn.nosum.http.Request;
-import cn.nosum.http.Response;
-import com.alibaba.fastjson.JSONObject;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-
-public  class GateWayHandler extends ChannelInboundHandlerAdapter {
-		private String msg ="请求URL是:";
-		@Override
-		public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-			if (msg instanceof Request){
-				Request request = (Request) msg;
-				Response response = new Response(ctx,request.getReq());
-				// 实际业务处理
-				JSONObject obj = new JSONObject();
-				obj.put("msg",this.msg+request.getUrl());
-				response.write(obj);
-			}
-		}
-
-		@Override
-		public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-
-		}
-	}

+ 0 - 30
src/main/java/cn/nosum/handler/HttpRequestHandler.java

@@ -1,30 +0,0 @@
-package cn.nosum.handler;
-
-import cn.nosum.http.Request;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.handler.codec.http.HttpRequest;
-
-public class HttpRequestHandler extends ChannelInboundHandlerAdapter {
-    @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        if (msg instanceof HttpRequest){
-            HttpRequest req = (HttpRequest) msg;
-            // TODO
-            Request request = new Request(ctx,req);
-            String uri=request.getUrl();
-            if (uri.equals("/favicon.ico")) {
-                return;
-            }
-            System.err.println(request.getParameter("name"));
-            System.err.println(request.getUrl());
-            // 传递request对象到下一个handler
-            ctx.fireChannelRead(request);
-        }
-    }
-
-    @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-
-    }
-}

+ 0 - 7
src/main/java/cn/nosum/handler/spi/IRequestHandler.java

@@ -1,7 +0,0 @@
-package cn.nosum.handler.spi;
-
-
-public interface IRequestHandler {
-    boolean doCheck(Object msg);
-    void doRun(Object msg);
-}

+ 0 - 48
src/main/java/cn/nosum/http/Request.java

@@ -1,48 +0,0 @@
-package cn.nosum.http;
-
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.http.HttpRequest;
-import io.netty.handler.codec.http.QueryStringDecoder;
-
-import java.util.List;
-import java.util.Map;
-
-public class Request {
-
-	private ChannelHandlerContext ctx;
-
-	private HttpRequest req;
-
-	public Request(ChannelHandlerContext ctx, HttpRequest req) {
-		this.ctx = ctx;
-		this.req = req;
-	}
-
-	public HttpRequest getReq() {
-		return req;
-	}
-
-	public String getUrl() {
-		return req.uri();
-	}
-
-	public String getMethod() {
-		return req.method().name();
-	}
-
-	public Map<String, List<String>> getParameters() {
-		QueryStringDecoder decoder = new QueryStringDecoder(req.uri());
-		return decoder.parameters();
-	}
-
-	public String getParameter(String name) {
-		Map<String, List<String>> params = getParameters();
-		List<String> param = params.get(name);
-		if (null == param) {
-			return null;
-		} else {
-			return param.get(0);
-		}
-	}
-}

+ 0 - 19
src/main/java/cn/nosum/http/Servlet.java

@@ -1,19 +0,0 @@
-package cn.nosum.http;
-
-public abstract class Servlet {
-	
-	public void service(Request request, Response response) throws Exception {
-		
-		//由service方法来决定,是调用doGet或者调用doPost
-		if("GET".equalsIgnoreCase(request.getMethod())){
-			doGet(request, response);
-		}else{
-			doPost(request, response);
-		}
-
-	}
-	
-	public abstract void doGet(Request request, Response response) throws Exception;
-	
-	public abstract void doPost(Request request, Response response) throws Exception;
-}

+ 16 - 0
src/main/resources/log4j.properties

@@ -0,0 +1,16 @@
+# 日记级别(单个级别) 文件/控制台
+log4j.rootLogger=debug, stdout,file
+
+# Redirect log messages to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# Rirect log messages to a log file
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=test.log
+log4j.appender.file.MaxFileSize=5MB
+log4j.appender.file.MaxBackupIndex=10
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n