update version

This commit is contained in:
yuye
2019-12-01 15:40:10 +08:00
parent 79ea619fb2
commit b149222ec5
25 changed files with 401 additions and 716 deletions
@@ -11,7 +11,7 @@ public @interface MarsReference {
String beanName();
String refName();
String refName() default "";
RefType refType() default RefType.METHOD;
}
+1 -1
View File
@@ -12,7 +12,7 @@
<dependencies>
<dependency>
<groupId>com.github.yuyenews</groupId>
<artifactId>mars-netty</artifactId>
<artifactId>mars-tomcat</artifactId>
</dependency>
</dependencies>
</project>
@@ -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";
@@ -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<paramTypes.length;i++){
Class paramType = paramTypes[i];
params[i] = jsonObject.toJavaObject(paramType);
}
return params;
} catch (Exception e){
throw new Exception("将API的参数适配到引用的方法上出异常了,请核对是否满足以下情况: [API所引用的方法的参数只可以使用自定对象或者Map]",e);
}
}
}
@@ -8,7 +8,6 @@ import com.mars.server.server.request.HttpMarsRequest;
import com.mars.server.server.request.HttpMarsResponse;
import com.mars.server.util.RequestUtil;
import com.mars.mvc.model.MarsMappingModel;
import io.netty.handler.codec.http.HttpMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +41,7 @@ public class ExecuteMars {
* @param response xiangying
* @return duix
*/
public Object execute(MarsMappingModel marsMappingModel, HttpMethod method, HttpMarsRequest request, HttpMarsResponse response) throws Exception {
public Object execute(MarsMappingModel marsMappingModel, String method, HttpMarsRequest request, HttpMarsResponse response) throws Exception {
try {
/* 校验请求方式 */
@@ -137,12 +136,12 @@ public class ExecuteMars {
* @param marsMappingModel
* @throws Exception
*/
private void checkRequestMethod(HttpMethod method,MarsMappingModel marsMappingModel) throws Exception {
private void checkRequestMethod(String method,MarsMappingModel marsMappingModel) throws Exception {
if(marsMappingModel == null){
throw new Exception("服务器上没有相应的接口");
}
String strMethod = method.name().toLowerCase();
String strMethod = method.toLowerCase();
String requestMethod = marsMappingModel.getReqMethod().name().toLowerCase();
if (!strMethod.equals(requestMethod)) {
/* 如果请求方式和MarsApi的映射不一致,则提示客户端 */
@@ -1,5 +1,6 @@
package com.mars.mvc.util;
import com.mars.core.constant.MarsConstant;
import com.mars.core.enums.DataType;
import com.mars.server.server.request.HttpMarsRequest;
import com.mars.server.server.request.HttpMarsResponse;
@@ -8,7 +9,6 @@ import com.mars.server.server.request.model.MarsFileUpLoad;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
/**
@@ -41,7 +41,11 @@ public class BuildParams {
} else if(responseClass.equals(cls)){
params[i] = response;
} else if(mapClass.equals(cls)) {
params[i] = request.getParemeters();
Map<String, Object> 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<Object> 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<String,MarsFileUpLoad> 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<String,MarsFileUpLoad> 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;
}
}
}
@@ -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();
}
}
}
@@ -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);
}
}
}
}
@@ -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<SocketChannel> {
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());
}
}
}
@@ -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);
}
}
+10 -2
View File
@@ -11,13 +11,21 @@
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>commons-fileupload</groupId>-->
<!-- <artifactId>commons-fileupload</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.github.yuyenews</groupId>
@@ -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<String, Object> paremeters;
/**
* 请求的文件
* 上传的文件
*/
private Map<String, MarsFileUpLoad> 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<String,MarsFileUpLoad> 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<String, Object> getParemeters() {
return paremeters;
public Map<String, Object> getParameters() {
Map<String, Object> params = new HashMap<>();
Map<String,String[]> parameterMap = httpRequest.getParameterMap();
for(String key : parameterMap.keySet()){
params.put(key,parameterMap.get(key));
}
return params;
}
/**
* 组装请求的参数
* @param paremeters 请求参数
*/
private void setParameters(Map<String, Object> paremeters) {
Object obj = paremeters.get(MarsConstant.REQUEST_FILE);
if (obj != null) {
this.files = (Map<String, MarsFileUpLoad>) obj;
paremeters.remove(MarsConstant.REQUEST_FILE);
}
this.paremeters = paremeters;
}
/**
* 获取单个请求的参数
* @param key 键
* @return 请求参数
*/
@SuppressWarnings("unchecked")
public Object getParameter(String key) {
List<Object> 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<Object> getParameterValues(String key) {
Object objs = paremeters.get(key);
if(objs != null) {
return (List<Object>)objs;
}
return null;
public String[] getParameterValues(String key) {
return httpRequest.getParameterValues(key);
}
/**
* 获取请求的文件
* @return 文件列表
*/
public Map<String, MarsFileUpLoad> getFiles() {
public Map<String, MarsFileUpLoad> 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<String, Object> 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();
}
}
@@ -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());
}
}
@@ -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<String, Object> parse() throws Exception {
HttpMethod method = fullReq.method();
Map<String, Object> parmMap = new HashMap<>();
if (HttpMethod.GET == method) {
// 是GET请求
QueryStringDecoder decoder = new QueryStringDecoder(fullReq.uri());
Map<String, List<String>> 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<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();
Map<String, MarsFileUpLoad> 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<String, Object> setAttr(InterfaceHttpData paramListItem,Map<String, Object> parmMap) throws Exception {
Attribute data = (Attribute) paramListItem;
List<Object> params = null;
Object paramItem = parmMap.get(data.getName());
if (paramItem == null) {
params = new ArrayList<>();
} else {
params = (List<Object>) paramItem;
}
params.add(data.getValue());
parmMap.put(data.getName(), params);
return parmMap;
}
/**
* 获取文件参数
* @param paramListItem
* @param files
* @return 返回参数集合
* @throws Exception 异常
*/
private Map<String, MarsFileUpLoad> setFile(InterfaceHttpData paramListItem,Map<String, MarsFileUpLoad> 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;
}
}
@@ -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;
}
}
@@ -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;
}
+1 -1
View File
@@ -7,7 +7,7 @@
<artifactId>Mars</artifactId>
<version>3.0.9</version>
</parent>
<artifactId>mars-netty</artifactId>
<artifactId>mars-tomcat</artifactId>
<dependencies>
<dependency>
@@ -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<String, MarsFileUpLoad> 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());
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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<String, MarsFileUpLoad> getFiles(HttpServletRequest request) throws Exception {
try {
if(!ServletFileUpload.isMultipartContent(request)) {
return null;
}
Map<String, MarsFileUpLoad> files = new HashMap<>();
List<FileItem> 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<FileItem> getFileItem(HttpServletRequest request) throws Exception {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload fileUpload = new ServletFileUpload(factory);
fileUpload.setFileSizeMax(fileSizeMax);
fileUpload.setSizeMax(sizeMax);
List<FileItem> fileItemList = fileUpload.parseRequest(new ServletRequestContext(request));
return fileItemList;
}
}
@@ -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());
}
}
+17 -5
View File
@@ -9,7 +9,7 @@
<modules>
<module>mars-core</module>
<module>mars-mvc</module>
<module>mars-netty</module>
<module>mars-tomcat</module>
<module>mars-server</module>
<module>mars-jdbc</module>
<module>mars-redis</module>
@@ -33,7 +33,7 @@
</dependency>
<dependency>
<groupId>com.github.yuyenews</groupId>
<artifactId>mars-netty</artifactId>
<artifactId>mars-tomcat</artifactId>
<version>${project.parent.version}</version>
</dependency>
@@ -54,10 +54,22 @@
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.42.Final</version>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.49</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>8.5.49</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>