diff --git a/mars-core/src/main/java/com/mars/core/annotation/MarsReference.java b/mars-core/src/main/java/com/mars/core/annotation/MarsReference.java index 5615bd7..26cbeaa 100644 --- a/mars-core/src/main/java/com/mars/core/annotation/MarsReference.java +++ b/mars-core/src/main/java/com/mars/core/annotation/MarsReference.java @@ -11,7 +11,7 @@ public @interface MarsReference { String beanName(); - String refName(); + String refName() default ""; RefType refType() default RefType.METHOD; } diff --git a/mars-mvc/pom.xml b/mars-mvc/pom.xml index 773dbb4..af97b0e 100644 --- a/mars-mvc/pom.xml +++ b/mars-mvc/pom.xml @@ -12,7 +12,7 @@ com.github.yuyenews - mars-netty + mars-tomcat \ No newline at end of file diff --git a/mars-mvc/src/main/java/com/mars/mvc/proxy/ExecuteRef.java b/mars-mvc/src/main/java/com/mars/mvc/proxy/ExecuteRef.java index 50197a0..ec465bd 100644 --- a/mars-mvc/src/main/java/com/mars/mvc/proxy/ExecuteRef.java +++ b/mars-mvc/src/main/java/com/mars/mvc/proxy/ExecuteRef.java @@ -88,12 +88,10 @@ public class ExecuteRef { Method[] methods = cls.getDeclaredMethods(); for(Method methodItem : methods){ if(methodItem.getName().equals(refName)){ - Class[] paramTypes = methodItem.getParameterTypes(); - Object[] refMethodParams = ParamUtil.getServiceParams(paramTypes,args); - if(refMethodParams == null){ + if(args == null || args.length < 1){ return methodItem.invoke(obj); } - return methodItem.invoke(obj,refMethodParams); + return methodItem.invoke(obj,args); } } return "errorRef"; diff --git a/mars-mvc/src/main/java/com/mars/mvc/proxy/ParamUtil.java b/mars-mvc/src/main/java/com/mars/mvc/proxy/ParamUtil.java deleted file mode 100644 index 41bff5a..0000000 --- a/mars-mvc/src/main/java/com/mars/mvc/proxy/ParamUtil.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.mars.mvc.proxy; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.mars.server.server.request.HttpMarsRequest; -import com.mars.server.server.request.HttpMarsResponse; - -/** - * 将API的参数转成引用的方法的参数 - */ -public class ParamUtil { - - /** - * 将API的参数转成引用的方法的参数 - * @param paramTypes 参数类型列表 - * @param args 参数值列表 - * @return - * @throws Exception - */ - public static Object[] getServiceParams(Class[] paramTypes, Object[] args) throws Exception { - try { - if(paramTypes == null || paramTypes.length < 0){ - return null; - } - if(args == null || args.length < 0){ - return new Object[paramTypes.length]; - } - - Object[] params = new Object[paramTypes.length]; - - /* 把api的参数值拿出来,转成json */ - JSONObject jsonObject = new JSONObject(); - for(Object arg : args){ - if(arg == null || arg instanceof HttpMarsResponse || arg instanceof HttpMarsRequest){ - continue; - } - - String jsonString = JSON.toJSONString(arg); - JSONObject argJson = JSONObject.parseObject(jsonString); - jsonObject.putAll(argJson); - } - - /* 把api的参数值 分别赋值到引用的方法的参数里 */ - for(int i=0;i paramMap = request.getParameters(); + if(paramMap != null){ + paramMap.put(MarsConstant.REQUEST_FILE,request.getFiles()); + } + params[i] = paramMap; } else { params[i] = getObject(cls,request); } @@ -64,53 +68,72 @@ public class BuildParams { Object obj = cls.getDeclaredConstructor().newInstance(); Field[] fields = cls.getDeclaredFields(); for(Field f : fields){ - List valList = request.getParameterValues(f.getName()); - MarsFileUpLoad marsFileUpLoad = request.getFile(f.getName()); - if(marsFileUpLoad != null){ - f.setAccessible(true); - f.set(obj, marsFileUpLoad); - } else if(valList != null && !valList.isEmpty()){ - f.setAccessible(true); - String fieldTypeName = f.getType().getSimpleName().toUpperCase(); - String valStr = valList.get(0).toString(); - switch (fieldTypeName){ - case DataType.INT: - case DataType.INTEGER: - f.set(obj,Integer.parseInt(valStr)); - break; - case DataType.BYTE: - f.set(obj,Byte.parseByte(valStr)); - break; - case DataType.STRING: - case DataType.CHAR: - case DataType.CHARACTER: - f.set(obj,valStr); - break; - case DataType.DOUBLE: - f.set(obj,Double.parseDouble(valStr)); - break; - case DataType.FLOAT: - f.set(obj,Float.parseFloat(valStr)); - break; - case DataType.LONG: - f.set(obj,Long.parseLong(valStr)); - break; - case DataType.SHORT: - f.set(obj,Short.valueOf(valStr)); - break; - case DataType.BOOLEAN: - f.set(obj,Boolean.parseBoolean(valStr)); - break; - case DataType.DATE: - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - f.set(obj,simpleDateFormat.parse(valStr)); - break; - case DataType.LIST: - f.set(obj,valList); - break; - } + f.setAccessible(true); + + String[] valList = request.getParameterValues(f.getName()); + Map marsFileUpLoadMap = request.getFiles(); + + if(f.getType().equals(MarsFileUpLoad.class) && marsFileUpLoadMap != null){ + f.set(obj, marsFileUpLoadMap.get(f.getName())); + } else if(f.getType().equals(MarsFileUpLoad[].class) && marsFileUpLoadMap != null && marsFileUpLoadMap.size() > 0){ + putMarsFileUploads(f,obj,marsFileUpLoadMap); + } else if(valList != null && valList.length > 0){ + putAttr(f,obj,valList); } } return obj; } + + private static void putMarsFileUploads(Field field, Object obj, Map marsFileUpLoadMap) throws Exception{ + MarsFileUpLoad[] marsFileUpLoads = new MarsFileUpLoad[marsFileUpLoadMap.size()]; + int index = 0; + for(String key : marsFileUpLoadMap.keySet()){ + marsFileUpLoads[index] = marsFileUpLoadMap.get(key); + index++; + } + field.set(obj, marsFileUpLoads); + } + + private static void putAttr(Field field, Object obj, String[] valList) throws Exception{ + String fieldTypeName = field.getType().getSimpleName().toUpperCase(); + String valStr = valList[0]; + switch (fieldTypeName){ + case DataType.INT: + case DataType.INTEGER: + field.set(obj,Integer.parseInt(valStr)); + break; + case DataType.BYTE: + field.set(obj,Byte.parseByte(valStr)); + break; + case DataType.STRING: + case DataType.CHAR: + case DataType.CHARACTER: + field.set(obj,valStr); + break; + case DataType.DOUBLE: + field.set(obj,Double.parseDouble(valStr)); + break; + case DataType.FLOAT: + field.set(obj,Float.parseFloat(valStr)); + break; + case DataType.LONG: + field.set(obj,Long.parseLong(valStr)); + break; + case DataType.SHORT: + field.set(obj,Short.valueOf(valStr)); + break; + case DataType.BOOLEAN: + field.set(obj,Boolean.parseBoolean(valStr)); + break; + case DataType.DATE: + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + field.set(obj,simpleDateFormat.parse(valStr)); + break; + default: + if (field.getType().equals(String[].class)){ + field.set(obj,valList); + } + break; + } + } } diff --git a/mars-netty/src/main/java/com/mars/netty/server/MarsServer.java b/mars-netty/src/main/java/com/mars/netty/server/MarsServer.java deleted file mode 100644 index 09b9465..0000000 --- a/mars-netty/src/main/java/com/mars/netty/server/MarsServer.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.mars.netty.server; - -import com.mars.core.constant.MarsConstant; -import com.mars.core.constant.MarsSpace; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelFuture; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * netty服务 - * @author yuye - * - */ -public class MarsServer { - - private static Logger log = LoggerFactory.getLogger(MarsServer.class); - - /** - * 获取全局存储空间 - */ - private static MarsSpace constants = MarsSpace.getEasySpace(); - - /** - * 启动netty服务 - * @param portNumber - */ - public static void start(final int portNumber) { - EventLoopGroup bossGroup = new NioEventLoopGroup(); - EventLoopGroup workerGroup = new NioEventLoopGroup(); - try { - - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup); - b.channel(NioServerSocketChannel.class); - b.childHandler(new MarsServerInitializer()); - - /* 服务器绑定端口监听 */ - ChannelFuture f = b.bind(portNumber).sync(); - - log.info("启动成功"); - - /* 标识netty是否已经启动 */ - constants.setAttr(MarsConstant.HAS_NETTY_START,"yes"); - - f.channel().closeFuture().sync(); - } catch (Exception e) { - log.error("启动netty报错",e); - } finally { - bossGroup.shutdownGracefully(); - workerGroup.shutdownGracefully(); - } - } -} diff --git a/mars-netty/src/main/java/com/mars/netty/server/MarsServerHandler.java b/mars-netty/src/main/java/com/mars/netty/server/MarsServerHandler.java deleted file mode 100644 index 64c407d..0000000 --- a/mars-netty/src/main/java/com/mars/netty/server/MarsServerHandler.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.mars.netty.server; - -import com.mars.netty.execute.RequestExecute; -import com.mars.netty.util.ResponseUtil; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.timeout.IdleStateEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; - -/** - * 接收netty服务 - * @author yuye - * - */ -public class MarsServerHandler extends ChannelInboundHandlerAdapter { - - private Logger log = LoggerFactory.getLogger(MarsServerHandler.class); - - /** - * 接收并处理 客户端请求 - */ - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - - FullHttpRequest httpRequest = null; - - try { - if (msg instanceof FullHttpRequest) { - - httpRequest = (FullHttpRequest) msg; - - RequestExecute requestExecute = new RequestExecute(); - requestExecute.setHttpRequest(httpRequest); - requestExecute.setCtx(ctx); - requestExecute.execute(); - } else { - ResponseUtil.sendServerError(ctx,"处理请求发生错误"); - } - - } catch (Exception e) { - log.error("处理请求失败!", e); - ResponseUtil.sendServerError(ctx,"处理请求发生错误"+e.getMessage()); - - /* 已经通过RequestExecute中的finally 释放请求了,所以这里,在出异常的时候,才释放 */ - try { - ctx.close(); - if(httpRequest != null){ - httpRequest.release(); - } - } catch (Exception e2) { - } - } - } - - - - /** - * 建立连接时,返回消息 - */ - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - ctx.writeAndFlush("客户端" + InetAddress.getLocalHost().getHostName() + "成功与服务端建立连接! "); - super.channelActive(ctx); - } - - /** - * 超时处理 - * @param ctx - * @param evt - * @throws Exception - */ - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if(evt instanceof IdleStateEvent){ - IdleStateEvent idleStateEvent = (IdleStateEvent)evt; - - switch (idleStateEvent.state()){ - case READER_IDLE: - case WRITER_IDLE: - ResponseUtil.sendTimeout(ctx,"请求超时"); - break; - default: - super.userEventTriggered(ctx, evt); - } - } - } -} diff --git a/mars-netty/src/main/java/com/mars/netty/server/MarsServerInitializer.java b/mars-netty/src/main/java/com/mars/netty/server/MarsServerInitializer.java deleted file mode 100644 index a6ae07a..0000000 --- a/mars-netty/src/main/java/com/mars/netty/server/MarsServerInitializer.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.mars.netty.server; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.mars.core.util.ConfigUtil; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.socket.SocketChannel; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.timeout.IdleStateHandler; - -/** - * 定义netty服务 - * @author yuye - * - */ -public class MarsServerInitializer extends ChannelInitializer { - - private int readTimeOut = 10; - private int writeTimeOut = 2000000000; - private int maxContentLength = 10485760; - - @Override - protected void initChannel(SocketChannel ch) throws Exception { - - /* 加载配置文件 */ - getConfig(); - - /* 处理http服务的关键handler */ - ChannelPipeline ph = ch.pipeline(); - ph.addLast("idlestatus", getIdleStateHandler()); - ph.addLast("encoder", new HttpResponseEncoder()); - ph.addLast("decoder", new HttpRequestDecoder()); - ph.addLast("aggregator", getHttpObjectAggregator()); - ph.addLast("handler", new MarsServerHandler());// 服务端业务逻辑 - } - - - private IdleStateHandler getIdleStateHandler(){ - return new IdleStateHandler(readTimeOut,writeTimeOut,0); - } - - private HttpObjectAggregator getHttpObjectAggregator(){ - return new HttpObjectAggregator(maxContentLength); - } - - /** - * 超时时间 - * @return - */ - private void getConfig() { - - JSONObject jsonObject = ConfigUtil.getConfig(); - Object timeOut = jsonObject.get("timeOut"); - Object maxContentLength2 = jsonObject.get("maxContentLength"); - - if(timeOut != null){ - JSONObject timeOut2 = JSONObject.parseObject(JSON.toJSONString(timeOut)); - Object readTimeOut2 = timeOut2.get("readTimeOut"); - Object writeTimeOut2 = timeOut2.get("writeTimeOut"); - - if(readTimeOut2!=null) { - readTimeOut = Integer.parseInt(readTimeOut2.toString()); - } - if(writeTimeOut2!=null) { - writeTimeOut = Integer.parseInt(writeTimeOut2.toString()); - } - } - - if(maxContentLength2 != null){ - maxContentLength = Integer.parseInt(maxContentLength2.toString()); - } - } -} diff --git a/mars-netty/src/main/java/com/mars/netty/util/ResponseUtil.java b/mars-netty/src/main/java/com/mars/netty/util/ResponseUtil.java deleted file mode 100644 index 817b5e4..0000000 --- a/mars-netty/src/main/java/com/mars/netty/util/ResponseUtil.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mars.netty.util; - -import com.mars.core.util.MesUtil; -import com.mars.server.server.request.HttpMarsResponse; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.HttpResponseStatus; - -/** - * 响应工具类 - */ -public class ResponseUtil { - - /** - * 禁止访问响应 - * @param ctx - */ - public static void sendForBidden(ChannelHandlerContext ctx, String ex){ - HttpMarsResponse response = new HttpMarsResponse(ctx); - response.send(MesUtil.getMes(403,ex).toJSONString(), HttpResponseStatus.FORBIDDEN); - } - - /** - * 出错响应 - * @param ctx - */ - public static void sendServerError(ChannelHandlerContext ctx, String ex){ - HttpMarsResponse response = new HttpMarsResponse(ctx); - response.send(MesUtil.getMes(500,ex).toJSONString(), HttpResponseStatus.INTERNAL_SERVER_ERROR); - } - - /** - * 请求超时响应 - * @param ctx - */ - public static void sendTimeout(ChannelHandlerContext ctx,String ex){ - HttpMarsResponse response = new HttpMarsResponse(ctx); - response.send(MesUtil.getMes(504,ex).toJSONString(), HttpResponseStatus.GATEWAY_TIMEOUT); - } -} diff --git a/mars-server/pom.xml b/mars-server/pom.xml index 85e23a2..89490f0 100644 --- a/mars-server/pom.xml +++ b/mars-server/pom.xml @@ -11,13 +11,21 @@ - io.netty - netty-all + org.apache.tomcat.embed + tomcat-embed-core + + + org.apache.tomcat + tomcat-servlet-api com.auth0 java-jwt + + + + com.github.yuyenews diff --git a/mars-server/src/main/java/com/mars/server/server/request/HttpMarsRequest.java b/mars-server/src/main/java/com/mars/server/server/request/HttpMarsRequest.java index 7f9aa91..b32b42f 100644 --- a/mars-server/src/main/java/com/mars/server/server/request/HttpMarsRequest.java +++ b/mars-server/src/main/java/com/mars/server/server/request/HttpMarsRequest.java @@ -1,82 +1,60 @@ package com.mars.server.server.request; -import com.mars.core.constant.MarsConstant; -import com.mars.server.server.jwt.JwtManager; import com.mars.server.server.request.model.MarsFileUpLoad; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.util.CharsetUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.util.*; /** - * 请求对象,对原生netty的request的补充 + * 请求对象,对原生tomcat的request的补充 * @author yuye * */ public class HttpMarsRequest { - private Logger logger = LoggerFactory.getLogger(HttpMarsRequest.class); + /** + * tomcat原生request + */ + private HttpServletRequest httpRequest; /** - * netty原生request + * tomcat原生通道 */ - private FullHttpRequest httpRequest; - - /** - * netty原生通道 - */ - private ChannelHandlerContext ctx; - - /** - * 请求体 - */ - private String body; + private HttpServletResponse response; /** - * 参数 - */ - private Map paremeters; - - /** - * 请求的文件 + * 上传的文件 */ private Map files; /** * 构造函数,框架自己用的,程序员用不到,用了也没意义 * @param httpRequest - * @param ctx + * @param response + * @param files */ - public HttpMarsRequest(FullHttpRequest httpRequest, ChannelHandlerContext ctx) { - this.body = getBody(httpRequest); - this.setParameters(getParams(httpRequest)); + public HttpMarsRequest(HttpServletRequest httpRequest, HttpServletResponse response,Map files) { this.httpRequest = httpRequest; - this.ctx = ctx; + this.response = response; + this.files = files; } /** * 获取请求方法 * @return 请求方法 */ - public HttpMethod getMethod() { - return httpRequest.method(); + public String getMethod() { + return httpRequest.getMethod(); } /** * 获取要请求的uri * @return 请求方法 */ - public String getUri() { - return httpRequest.uri(); + public String getUrl() { + return httpRequest.getRequestURL().toString(); } /** @@ -85,50 +63,30 @@ public class HttpMarsRequest { * @return 头数据 */ public Object getHeader(String key) { - return httpRequest.headers().get(key); - } - - /** - * 获取请求头 - * @return 请求头 - */ - public HttpHeaders getHeaders() { - return httpRequest.headers(); + return httpRequest.getHeader(key); } /** * 获取请求的参数集 * @return 请求参数 */ - public Map getParemeters() { - return paremeters; + public Map getParameters() { + Map params = new HashMap<>(); + + Map parameterMap = httpRequest.getParameterMap(); + for(String key : parameterMap.keySet()){ + params.put(key,parameterMap.get(key)); + } + return params; } - /** - * 组装请求的参数 - * @param paremeters 请求参数 - */ - private void setParameters(Map paremeters) { - Object obj = paremeters.get(MarsConstant.REQUEST_FILE); - if (obj != null) { - this.files = (Map) obj; - paremeters.remove(MarsConstant.REQUEST_FILE); - } - this.paremeters = paremeters; - } - /** * 获取单个请求的参数 * @param key 键 * @return 请求参数 */ - @SuppressWarnings("unchecked") public Object getParameter(String key) { - List lis = getParameterValues(key); - if (lis != null) { - return lis.get(0); - } - return null; + return httpRequest.getParameter(key); } /** @@ -136,19 +94,15 @@ public class HttpMarsRequest { * @param key 键 * @return 请求参数 */ - public List getParameterValues(String key) { - Object objs = paremeters.get(key); - if(objs != null) { - return (List)objs; - } - return null; + public String[] getParameterValues(String key) { + return httpRequest.getParameterValues(key); } /** * 获取请求的文件 * @return 文件列表 */ - public Map getFiles() { + public Map getFiles() throws Exception { return files; } @@ -158,69 +112,27 @@ public class HttpMarsRequest { * @param name 名称 * @return 单个文件 */ - public MarsFileUpLoad getFile(String name) { - if (files != null && files.size() > 0) { + public MarsFileUpLoad getFile(String name) throws Exception { + if (files != null){ return files.get(name); - } else { - return null; } - } - - /** - * 获取请求的url - * @return 请求的路径 - */ - public String getUrl() { - return httpRequest.uri(); - } - - /** - * 获取请求的body - * @return 请求体 - */ - public String getBody() { - return body; + return null; } /** - * 获取netty原生request + * 获取tomcat原生request * @return 原生请求对象 */ - public FullHttpRequest getFullHttpRequest() { + public HttpServletRequest getHttpServletRequest() { return httpRequest; } /** - * 获取body参数 - * - * @param request 请求对象 - * @return 请求体 - */ - private String getBody(FullHttpRequest request) { - ByteBuf buf = request.content(); - return buf.toString(CharsetUtil.UTF_8); - } - - /** - * 将GET, POST所有请求参数转换成Map对象 - * @param request 原生请求对象 - * @return 请求参数 - */ - private Map getParams(FullHttpRequest request) { - try { - return new RequestParser(request).parse(); - } catch (Exception e) { - logger.error("从请求中获取参数,报错",e); - } - return new HashMap<>(); - } - - /** - * 获取JWT管理类对象 + * 获取Session * @return jwt */ - public JwtManager getJwtManager(){ - return JwtManager.getJwtManager(); + public HttpSession getSession(){ + return httpRequest.getSession(); } /** @@ -228,11 +140,6 @@ public class HttpMarsRequest { * @return ip */ public String getIp() { - String clientIP = String.valueOf(httpRequest.headers().get("X-Forwarded-For")); - if (clientIP == null || clientIP.equals("null")) { - InetSocketAddress insocket = (InetSocketAddress) this.ctx.channel().remoteAddress(); - clientIP = insocket.getAddress().getHostAddress(); - } - return clientIP; + return httpRequest.getRemoteHost(); } } diff --git a/mars-server/src/main/java/com/mars/server/server/request/HttpMarsResponse.java b/mars-server/src/main/java/com/mars/server/server/request/HttpMarsResponse.java index dd08180..b23e246 100644 --- a/mars-server/src/main/java/com/mars/server/server/request/HttpMarsResponse.java +++ b/mars-server/src/main/java/com/mars/server/server/request/HttpMarsResponse.java @@ -1,12 +1,9 @@ package com.mars.server.server.request; import com.mars.server.server.request.model.CrossDomain; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.*; -import io.netty.util.CharsetUtil; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; @@ -22,7 +19,7 @@ public class HttpMarsResponse { /** * netty原生通道 */ - private ChannelHandlerContext ctx; + private HttpServletResponse response; /** * 响应头 @@ -33,19 +30,19 @@ public class HttpMarsResponse { /** * 构造函数,框架自己用的,程序员用不到,用了也没意义 * - * @param ctx netty原生通道 + * @param response netty原生通道 */ - public HttpMarsResponse(ChannelHandlerContext ctx) { - this.ctx = ctx; + public HttpMarsResponse(HttpServletResponse response) { + this.response = response; this.header = new HashMap<>(); } /** - * 获取netty原生通道 + * 获取tomcat原生response * @return netty原生通道 */ - public ChannelHandlerContext getChannelHandlerContext() { - return ctx; + public HttpServletResponse geHttpServletResponse() { + return response; } /** @@ -64,35 +61,32 @@ public class HttpMarsResponse { * @param context 消息 */ public void send(String context) { - send(context, HttpResponseStatus.OK); - } + PrintWriter out = null; + try { + crossDomain(); + loadHeader(); - - /** - * 响应数据 - * - * @param context 消息 - * @param status 状态 - */ - public void send(String context, HttpResponseStatus status) { - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, - Unpooled.copiedBuffer(context, CharsetUtil.UTF_8)); - - crossDomain(response); - loadHeader(response); - - response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/json; charset=UTF-8"); - ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + response.setContentType("text/json;charset=UTF-8"); + response.setCharacterEncoding("UTF-8"); + out = response.getWriter(); + out.println(context); + } catch (Exception e){ + // 不处理 + } finally { + if (out != null){ + out.flush(); + out.close(); + } + } } /** * 加载设置的header - * @param response */ - private void loadHeader(FullHttpResponse response){ + private void loadHeader(){ if (header != null && !header.isEmpty()) { for (String key : header.keySet()) { - response.headers().set(key, header.get(key)); + response.setHeader(key, header.get(key)); } } } @@ -100,12 +94,12 @@ public class HttpMarsResponse { /** * 设置跨域 */ - private void crossDomain(FullHttpResponse response) { + private void crossDomain() { CrossDomain crossDomain = CrossDomain.getCrossDomain(); - response.headers().set("Access-Control-Allow-Origin", crossDomain.getOrigin()); - response.headers().set("Access-Control-Allow-Methods", crossDomain.getMethods()); - response.headers().set("Access-Control-Max-Age", crossDomain.getMaxAge()); - response.headers().set("Access-Control-Allow-Headers", crossDomain.getHeaders()); - response.headers().set("Access-Control-Allow-Credentials", crossDomain.getCredentials()); + response.setHeader("Access-Control-Allow-Origin", crossDomain.getOrigin()); + response.setHeader("Access-Control-Allow-Methods", crossDomain.getMethods()); + response.setHeader("Access-Control-Max-Age", crossDomain.getMaxAge()); + response.setHeader("Access-Control-Allow-Headers", crossDomain.getHeaders()); + response.setHeader("Access-Control-Allow-Credentials", crossDomain.getCredentials()); } } diff --git a/mars-server/src/main/java/com/mars/server/server/request/RequestParser.java b/mars-server/src/main/java/com/mars/server/server/request/RequestParser.java deleted file mode 100644 index d7a5f18..0000000 --- a/mars-server/src/main/java/com/mars/server/server/request/RequestParser.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.mars.server.server.request; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import com.mars.core.constant.MarsConstant; -import com.mars.server.server.request.model.MarsFileUpLoad; - -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.QueryStringDecoder; -import io.netty.handler.codec.http.multipart.*; - -/** - * 参数解析器 - * - * @author yuye - * - */ -public class RequestParser { - - private FullHttpRequest fullReq; - - /** - * 构造一个解析器 - * - * @param req 请求对象 - */ - public RequestParser(FullHttpRequest req) { - this.fullReq = req; - } - - /** - * 解析请求参数 - * - * @return 包含所有请求参数的键值对, 如果没有参数, 则返回空Map - * - * @throws Exception 异常 - */ - public Map parse() throws Exception { - HttpMethod method = fullReq.method(); - - Map parmMap = new HashMap<>(); - - if (HttpMethod.GET == method) { - // 是GET请求 - QueryStringDecoder decoder = new QueryStringDecoder(fullReq.uri()); - Map> params = decoder.parameters(); - for(String key : params.keySet()){ - parmMap.put(key, params.get(key)); - } - } else if (HttpMethod.POST == method) { - // 是POST请求 - HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(fullReq); - decoder.offer(fullReq); - - List parmList = decoder.getBodyHttpDatas(); - - Map files = new Hashtable<>(); - - for (InterfaceHttpData paramListItem : parmList) { - if (paramListItem instanceof Attribute) { - parmMap = setAttr(paramListItem,parmMap); - } else if (paramListItem instanceof FileUpload) { - files = setFile(paramListItem,files); - } - } - parmMap.put(MarsConstant.REQUEST_FILE, files); - } - - return parmMap; - } - - /** - * 获取常规参数 - * @param paramListItem - * @param parmMap - * @return 返回参数集合 - * @throws Exception 异常 - */ - private Map setAttr(InterfaceHttpData paramListItem,Map parmMap) throws Exception { - Attribute data = (Attribute) paramListItem; - List params = null; - Object paramItem = parmMap.get(data.getName()); - if (paramItem == null) { - params = new ArrayList<>(); - } else { - params = (List) paramItem; - } - params.add(data.getValue()); - parmMap.put(data.getName(), params); - - return parmMap; - } - - /** - * 获取文件参数 - * @param paramListItem - * @param files - * @return 返回参数集合 - * @throws Exception 异常 - */ - private Map setFile(InterfaceHttpData paramListItem,Map files) throws Exception { - FileUpload fileUpload = (FileUpload) paramListItem; - - byte[] bs = fileUpload.get(); - - InputStream inputStream = new ByteArrayInputStream(bs); - - MarsFileUpLoad upLoad = new MarsFileUpLoad(); - upLoad.setFileName(fileUpload.getFilename()); - upLoad.setInputStream(inputStream); - upLoad.setName(fileUpload.getName()); - upLoad.setBytes(bs); - - files.put(fileUpload.getName(), upLoad); - - return files; - } -} diff --git a/mars-server/src/main/java/com/mars/server/server/request/model/MarsFileUpLoad.java b/mars-server/src/main/java/com/mars/server/server/request/model/MarsFileUpLoad.java index 6c8f05b..67facce 100644 --- a/mars-server/src/main/java/com/mars/server/server/request/model/MarsFileUpLoad.java +++ b/mars-server/src/main/java/com/mars/server/server/request/model/MarsFileUpLoad.java @@ -24,11 +24,6 @@ public class MarsFileUpLoad { */ private InputStream inputStream; - /** - * 二进制流 - */ - private byte[] bytes; - public String getName() { return name; } @@ -53,11 +48,4 @@ public class MarsFileUpLoad { this.inputStream = inputStream; } - public byte[] getBytes() { - return bytes; - } - - public void setBytes(byte[] bytes) { - this.bytes = bytes; - } } diff --git a/mars-server/src/main/java/com/mars/server/util/RequestUtil.java b/mars-server/src/main/java/com/mars/server/util/RequestUtil.java index b4d927b..ded54d9 100644 --- a/mars-server/src/main/java/com/mars/server/util/RequestUtil.java +++ b/mars-server/src/main/java/com/mars/server/util/RequestUtil.java @@ -16,9 +16,11 @@ public class RequestUtil { */ public static String getUriName(HttpMarsRequest request) { /* 获取路径 */ - String uri = request.getUri(); + String uri = request.getUrl(); if(uri.indexOf("?")>-1) { - uri = uri.substring(0,uri.indexOf("?")); + uri = uri.substring(uri.lastIndexOf("/"),uri.indexOf("?")); + } else { + uri = uri.substring(uri.lastIndexOf("/")); } return uri; } diff --git a/mars-netty/pom.xml b/mars-tomcat/pom.xml similarity index 90% rename from mars-netty/pom.xml rename to mars-tomcat/pom.xml index 2bb94fc..a3ff720 100644 --- a/mars-netty/pom.xml +++ b/mars-tomcat/pom.xml @@ -7,7 +7,7 @@ Mars 3.0.9 - mars-netty + mars-tomcat diff --git a/mars-netty/src/main/java/com/mars/netty/execute/RequestExecute.java b/mars-tomcat/src/main/java/com/mars/netty/execute/RequestExecute.java similarity index 61% rename from mars-netty/src/main/java/com/mars/netty/execute/RequestExecute.java rename to mars-tomcat/src/main/java/com/mars/netty/execute/RequestExecute.java index 18e8135..f2d5ce6 100644 --- a/mars-netty/src/main/java/com/mars/netty/execute/RequestExecute.java +++ b/mars-tomcat/src/main/java/com/mars/netty/execute/RequestExecute.java @@ -1,19 +1,20 @@ package com.mars.netty.execute; -import com.mars.core.constant.MarsConstant; import com.mars.core.ncfg.mvc.CoreServletClass; import com.mars.core.util.MesUtil; import com.mars.netty.par.factory.ParamAndResultFactory; +import com.mars.netty.util.FileUpLoad; import com.mars.server.server.request.HttpMarsRequest; import com.mars.server.server.request.HttpMarsResponse; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpResponseStatus; +import com.mars.server.server.request.model.MarsFileUpLoad; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Map; /** * 处理请求的线程 @@ -27,27 +28,36 @@ public class RequestExecute { /** * netty的request对象 */ - private FullHttpRequest httpRequest; + private HttpServletRequest httpRequest; - private ChannelHandlerContext ctx; + private HttpServletResponse httpResponse; - public void setHttpRequest(FullHttpRequest httpRequest) { + public void setHttpRequest(HttpServletRequest httpRequest) { this.httpRequest = httpRequest; } - public void setCtx(ChannelHandlerContext ctx) { - this.ctx = ctx; + public void setHttpResponse(HttpServletResponse response) { + this.httpResponse = response; } public void execute() { /* 组装httpRequest对象 */ - HttpMarsRequest request = new HttpMarsRequest(httpRequest,ctx); + HttpMarsRequest request = null; /* 组装httpResponse对象 */ - HttpMarsResponse response = new HttpMarsResponse(ctx); + HttpMarsResponse response = null; try { + /* 从请求中获取上传的文件 */ + Map fileUpLoadMap = FileUpLoad.getFiles(httpRequest); + + /* 组装httpRequest对象 */ + request = new HttpMarsRequest(httpRequest,httpResponse,fileUpLoadMap); + + /* 组装httpResponse对象 */ + response = new HttpMarsResponse(httpResponse); + /* 通过反射执行核心servlet */ Class cls = CoreServletClass.getCls(); @@ -59,18 +69,10 @@ public class RequestExecute { ParamAndResultFactory.getBaseParamAndResult().result(response,result); } catch (InvocationTargetException e){ log.error("处理请求的时候出错",e); - response.send(MesUtil.getMes(500,"处理请求发生错误:"+e+",message:"+e.getTargetException().getMessage()).toJSONString(), HttpResponseStatus.INTERNAL_SERVER_ERROR); + response.send(MesUtil.getMes(500,"处理请求发生错误:"+e+",message:"+e.getTargetException().getMessage()).toJSONString()); } catch (Exception e) { log.error("处理请求的时候出错",e); - response.send(MesUtil.getMes(500,"处理请求发生错误:"+e+",message:"+e.getMessage()).toJSONString(), HttpResponseStatus.INTERNAL_SERVER_ERROR); - } finally { - try{ - // 释放请求 - ctx.close(); - httpRequest.release(); - } catch (Exception e){ - log.error("释放请求出错",e); - } + response.send(MesUtil.getMes(500,"处理请求发生错误:"+e+",message:"+e.getMessage()).toJSONString()); } } } diff --git a/mars-netty/src/main/java/com/mars/netty/par/base/BaseParamAndResult.java b/mars-tomcat/src/main/java/com/mars/netty/par/base/BaseParamAndResult.java similarity index 100% rename from mars-netty/src/main/java/com/mars/netty/par/base/BaseParamAndResult.java rename to mars-tomcat/src/main/java/com/mars/netty/par/base/BaseParamAndResult.java diff --git a/mars-netty/src/main/java/com/mars/netty/par/factory/ParamAndResultFactory.java b/mars-tomcat/src/main/java/com/mars/netty/par/factory/ParamAndResultFactory.java similarity index 100% rename from mars-netty/src/main/java/com/mars/netty/par/factory/ParamAndResultFactory.java rename to mars-tomcat/src/main/java/com/mars/netty/par/factory/ParamAndResultFactory.java diff --git a/mars-tomcat/src/main/java/com/mars/netty/server/MarsServer.java b/mars-tomcat/src/main/java/com/mars/netty/server/MarsServer.java new file mode 100644 index 0000000..2dbed8e --- /dev/null +++ b/mars-tomcat/src/main/java/com/mars/netty/server/MarsServer.java @@ -0,0 +1,51 @@ +package com.mars.netty.server; + +import com.mars.core.constant.MarsConstant; +import com.mars.core.constant.MarsSpace; +import org.apache.catalina.Context; +import org.apache.catalina.startup.Tomcat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * netty服务 + * @author yuye + * + */ +public class MarsServer { + + private static Logger log = LoggerFactory.getLogger(MarsServer.class); + + /** + * 获取全局存储空间 + */ + private static MarsSpace constants = MarsSpace.getEasySpace(); + + /** + * 启动netty服务 + * @param portNumber + */ + public static void start(final int portNumber) { + try { + Tomcat tomcat = new Tomcat(); + tomcat.setPort(portNumber); + tomcat.setBaseDir("."); + + final Context context = tomcat.addContext("/", null); + Tomcat.addServlet(context, "dispatch", new MarsServerHandler()); + context.addServletMappingDecoded("/*", "dispatch"); + + tomcat.init(); + tomcat.start(); + + log.info("启动成功"); + /* 标识tomcat是否已经启动 */ + constants.setAttr(MarsConstant.HAS_NETTY_START,"yes"); + + tomcat.getServer().await(); + + } catch (Exception e) { + log.error("启动netty报错",e); + } + } +} diff --git a/mars-tomcat/src/main/java/com/mars/netty/server/MarsServerHandler.java b/mars-tomcat/src/main/java/com/mars/netty/server/MarsServerHandler.java new file mode 100644 index 0000000..61c270f --- /dev/null +++ b/mars-tomcat/src/main/java/com/mars/netty/server/MarsServerHandler.java @@ -0,0 +1,57 @@ +package com.mars.netty.server; + +import com.mars.netty.execute.RequestExecute; +import com.mars.netty.util.ResponseUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 接收netty服务 + * @author yuye + * + */ +@MultipartConfig +public class MarsServerHandler extends HttpServlet { + + private Logger log = LoggerFactory.getLogger(MarsServerHandler.class); + + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + try { + req.setCharacterEncoding("UTF-8"); + resp.setCharacterEncoding("UTF-8"); + + RequestExecute requestExecute = new RequestExecute(); + requestExecute.setHttpRequest(req); + requestExecute.setHttpResponse(resp); + requestExecute.execute(); + + } catch (Exception e) { + log.error("处理请求失败!", e); + ResponseUtil.sendServerError(resp,"处理请求发生错误"+e.getMessage()); + } + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doPost(req,resp); + } + + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doPost(req,resp); + } + + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + doPost(req,resp); + } +} diff --git a/mars-tomcat/src/main/java/com/mars/netty/util/FileUpLoad.java b/mars-tomcat/src/main/java/com/mars/netty/util/FileUpLoad.java new file mode 100644 index 0000000..2b075eb --- /dev/null +++ b/mars-tomcat/src/main/java/com/mars/netty/util/FileUpLoad.java @@ -0,0 +1,64 @@ +package com.mars.netty.util; + +import com.mars.server.server.request.model.MarsFileUpLoad; +import org.apache.tomcat.util.http.fileupload.FileItem; +import org.apache.tomcat.util.http.fileupload.FileItemFactory; +import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; +import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload; +import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FileUpLoad { + + /** + * 默认单个文件2M + */ + private static int fileSizeMax = 2*1024*1024; + + /** + * 默认总文件数10M + */ + private static int sizeMax = 10*1024*1024; + + public static Map getFiles(HttpServletRequest request) throws Exception { + try { + if(!ServletFileUpload.isMultipartContent(request)) { + return null; + } + Map files = new HashMap<>(); + + List fileItemList = getFileItem(request); + if(fileItemList != null){ + for(FileItem item : fileItemList){ + if(item.isFormField()){ + continue; + } + MarsFileUpLoad marsFileUpLoad = new MarsFileUpLoad(); + marsFileUpLoad.setName(item.getFieldName()); + marsFileUpLoad.setInputStream(item.getInputStream()); + marsFileUpLoad.setFileName(item.getName()); + files.put(marsFileUpLoad.getName(),marsFileUpLoad); + } + } + return files; + } catch (Exception e){ + throw new Exception("接受上传的文件出错",e); + } + } + + public static List getFileItem(HttpServletRequest request) throws Exception { + + FileItemFactory factory = new DiskFileItemFactory(); + ServletFileUpload fileUpload = new ServletFileUpload(factory); + + fileUpload.setFileSizeMax(fileSizeMax); + fileUpload.setSizeMax(sizeMax); + List fileItemList = fileUpload.parseRequest(new ServletRequestContext(request)); + + return fileItemList; + } +} diff --git a/mars-tomcat/src/main/java/com/mars/netty/util/ResponseUtil.java b/mars-tomcat/src/main/java/com/mars/netty/util/ResponseUtil.java new file mode 100644 index 0000000..231b5d0 --- /dev/null +++ b/mars-tomcat/src/main/java/com/mars/netty/util/ResponseUtil.java @@ -0,0 +1,21 @@ +package com.mars.netty.util; + +import com.mars.core.util.MesUtil; +import com.mars.server.server.request.HttpMarsResponse; + +import javax.servlet.http.HttpServletResponse; + +/** + * 响应工具类 + */ +public class ResponseUtil { + + /** + * 出错响应 + * @param response + */ + public static void sendServerError(HttpServletResponse response, String ex){ + HttpMarsResponse marsResponse = new HttpMarsResponse(response); + marsResponse.send(MesUtil.getMes(500,ex).toJSONString()); + } +} diff --git a/pom.xml b/pom.xml index a4a32dc..3ce28bb 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ mars-core mars-mvc - mars-netty + mars-tomcat mars-server mars-jdbc mars-redis @@ -33,7 +33,7 @@ com.github.yuyenews - mars-netty + mars-tomcat ${project.parent.version} @@ -54,10 +54,22 @@ - io.netty - netty-all - 4.1.42.Final + org.apache.tomcat.embed + tomcat-embed-core + 8.5.49 + + org.apache.tomcat + tomcat-servlet-api + 8.5.49 + + + + commons-fileupload + commons-fileupload + 1.4 + + com.alibaba