Răsfoiți Sursa

添加拦截器、修复RequestBody的BUG、新增是否抛出异常配置

mxd 5 ani în urmă
părinte
comite
a3f4680fc4

+ 1 - 1
pom.xml

@@ -11,7 +11,7 @@
     </parent>
     <groupId>org.ssssssss</groupId>
     <artifactId>ssssssss-core</artifactId>
-    <version>0.0.1</version>
+    <version>0.0.2</version>
     <packaging>jar</packaging>
     <name>ssssssss-core</name>
     <description>auto generate http api based on xml</description>

+ 66 - 15
src/main/java/org/ssssssss/context/RequestContext.java

@@ -1,14 +1,16 @@
 package org.ssssssss.context;
 
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.ServletWebRequest;
+import org.springframework.web.servlet.HandlerMapping;
 import org.ssssssss.expression.ExpressionEngine;
+import org.ssssssss.session.Statement;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
 
-public class RequestContext extends HashMap<String,Object> {
+public class RequestContext extends HashMap<String, Object> {
 
     private HttpServletRequest request;
 
@@ -16,17 +18,35 @@ public class RequestContext extends HashMap<String,Object> {
 
     private ExpressionEngine engine;
 
-    public RequestContext(HttpServletRequest request,ExpressionEngine engine) {
+    private Map<String, String> pathVariables;
+
+    private String requestMapping;
+
+    private String requestMethod;
+
+    private Object requestBody;
+
+    private Statement statement;
+
+    public RequestContext(HttpServletRequest request, ExpressionEngine engine) {
         this.request = request;
         this.engine = engine;
         Enumeration<String> parameterNames = request.getParameterNames();
-        while (parameterNames.hasMoreElements()){
+        while (parameterNames.hasMoreElements()) {
             String key = parameterNames.nextElement();
-            put(key,request.getParameter(key));
+            put(key, request.getParameter(key));
         }
-        put("header",new HeaderContext(request));
-        put("cookie",new CookieContext(request));
-        put("session",new SessionContext(request.getSession()));
+        NativeWebRequest webRequest = new ServletWebRequest(request);
+        // 解析requestMapping
+        this.requestMapping = (String) webRequest.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
+        // 解析pathVariable
+        this.pathVariables = (Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
+        this.putAll(this.pathVariables);
+        // 请求方法
+        this.requestMethod = request.getMethod();
+        put("header", new HeaderContext(request));
+        put("cookie", new CookieContext(request));
+        put("session", new SessionContext(request.getSession()));
     }
 
     /**
@@ -41,12 +61,13 @@ public class RequestContext extends HashMap<String,Object> {
      *
      * @param value
      */
-    public void addParameter(Object value){
+    public void addParameter(Object value) {
         this.parameters.add(value);
     }
 
     /**
      * 获取SQL参数
+     *
      * @return
      */
     public List<Object> getParameters() {
@@ -55,9 +76,39 @@ public class RequestContext extends HashMap<String,Object> {
 
     /**
      * 执行表达式
-     * @param expression    表达式
+     *
+     * @param expression 表达式
      */
-    public Object evaluate(String expression){
-        return engine.executeWrap(expression,this);
+    public Object evaluate(String expression) {
+        return engine.executeWrap(expression, this);
+    }
+
+    public Object getRequestBody() {
+        return requestBody;
+    }
+
+    public void setRequestBody(Object requestBody) {
+        this.requestBody = requestBody;
+        this.put("body", this.requestBody);
+    }
+
+    public Map<String, String> getPathVariables() {
+        return pathVariables;
+    }
+
+    public String getRequestMapping() {
+        return requestMapping;
+    }
+
+    public String getRequestMethod() {
+        return requestMethod;
+    }
+
+    public Statement getStatement() {
+        return statement;
+    }
+
+    public void setStatement(Statement statement) {
+        this.statement = statement;
     }
 }

+ 4 - 0
src/main/java/org/ssssssss/exception/S8Exception.java

@@ -5,4 +5,8 @@ public class S8Exception extends RuntimeException{
     public S8Exception(String message) {
         super(message);
     }
+
+    public S8Exception(String message, Throwable cause) {
+        super(message, cause);
+    }
 }

+ 39 - 16
src/main/java/org/ssssssss/executor/RequestExecutor.java

@@ -6,12 +6,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.context.request.NativeWebRequest;
-import org.springframework.web.context.request.RequestAttributes;
-import org.springframework.web.context.request.ServletWebRequest;
-import org.springframework.web.servlet.HandlerMapping;
 import org.ssssssss.context.RequestContext;
+import org.ssssssss.exception.S8Exception;
 import org.ssssssss.expression.ExpressionEngine;
+import org.ssssssss.interceptor.RequestInterceptor;
 import org.ssssssss.model.JsonBean;
 import org.ssssssss.session.Configuration;
 import org.ssssssss.session.Statement;
@@ -25,6 +23,7 @@ import org.w3c.dom.NodeList;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.xml.xpath.XPathConstants;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -38,8 +37,11 @@ public class RequestExecutor {
     private ExpressionEngine expressionEngine;
 
     private static Logger logger = LoggerFactory.getLogger(RequestExecutor.class);
+
     private Map<String, IValidator> validators = new HashMap<>();
 
+    private List<RequestInterceptor> requestInterceptors = new ArrayList<>();
+
     public void addValidator(IValidator validator) {
         this.validators.put(validator.support(), validator);
     }
@@ -58,33 +60,54 @@ public class RequestExecutor {
 
     /**
      * http请求入口
+     *
+     * @param request
+     * @return
+     */
+    @ResponseBody
+    public Object invoke(HttpServletRequest request) {
+        return invoke(request, null);
+    }
+
+    /**
+     * http请求入口(带RequestBody)
      */
     @ResponseBody
     public Object invoke(HttpServletRequest request, @RequestBody(required = false) Object requestBody) {
         try {
-            NativeWebRequest webRequest = new ServletWebRequest(request);
-            // 解析requestMapping
-            String requestMapping = (String) webRequest.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
-            // 解析pathVariable
-            Map<String, String> pathVariables = (Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
             // 创建RequestContex对象,供后续使用
             RequestContext requestContext = new RequestContext(request, expressionEngine);
             if (!requestContext.containsKey("body")) {
-                requestContext.put("body", requestBody);
+                requestContext.setRequestBody(requestBody);
             }
-            if (pathVariables != null) {
-                requestContext.putAll(pathVariables);
+            Statement statement = configuration.getStatement(requestContext.getRequestMapping());
+            requestContext.setStatement(statement);
+            // 执行前置拦截器
+            for (RequestInterceptor requestInterceptor : requestInterceptors) {
+                Object value = requestInterceptor.preHandle(requestContext);
+                if (value != null) {
+                    return value;
+                }
             }
-            Statement statement = configuration.getStatement(requestMapping);
             // 执行校验
             Object value = validate(statement, requestContext);
             if (value != null) {
                 return value;
             }
-            // 执行SQL
-            value = statementExecutor.execute(statement, requestContext);
-            return new JsonBean<>(value);
+            // 执行语句
+            value = new JsonBean<>(statementExecutor.execute(statement, requestContext));
+            // 执行后置拦截器
+            for (RequestInterceptor requestInterceptor : requestInterceptors) {
+                Object target = requestInterceptor.postHandle(requestContext, value);
+                if (target != null) {
+                    return target;
+                }
+            }
+            return value;
         } catch (Exception e) {
+            if (configuration.isThrowException()) {
+                throw new S8Exception("ssssssss执行出错", e);
+            }
             logger.error("系统出现错误", e);
             return new JsonBean<>(-1, e.getMessage());
         }

+ 31 - 0
src/main/java/org/ssssssss/interceptor/RequestInterceptor.java

@@ -0,0 +1,31 @@
+package org.ssssssss.interceptor;
+
+import org.ssssssss.context.RequestContext;
+
+/**
+ * 请求拦截器
+ */
+public interface RequestInterceptor {
+
+    /**
+     * 请求之前执行
+     *
+     * @return 当返回对象时,直接将此对象返回到页面,返回null时,继续执行后续操作
+     * @throws Exception
+     */
+    default Object preHandle(RequestContext context) throws Exception {
+        return null;
+    }
+
+
+    /**
+     * 执行完毕之后执行
+     * @param value 即将要返回到页面的值
+     * @return 返回到页面的对象,当返回null时执行后续拦截器,否则直接返回该值,不执行后续拦截器
+     * @throws Exception
+     */
+    default Object postHandle(RequestContext context, Object value) throws Exception {
+        return null;
+    }
+
+}

+ 23 - 1
src/main/java/org/ssssssss/session/Configuration.java

@@ -33,6 +33,11 @@ public class Configuration implements InitializingBean {
      */
     private Method requestHandleMethod;
 
+    /**
+     * Http请求(带RequestBody)处理方法
+     */
+    private Method requestWithRequestBodyHandleMethod;
+
     /**
      * xml位置
      */
@@ -48,6 +53,11 @@ public class Configuration implements InitializingBean {
      */
     private boolean banner;
 
+    /**
+     * 执行出错时是否抛异常
+     */
+    private boolean throwException = false;
+
     /**
      * 缓存已加载的statement(request-mapping映射)
      */
@@ -97,7 +107,7 @@ public class Configuration implements InitializingBean {
         // 添加至缓存
         statementMappingMap.put(statement.getRequestMapping(), statement);
         // 注册接口
-        requestMappingHandlerMapping.registerMapping(requestMappingInfo,requestHandler,requestHandleMethod);
+        requestMappingHandlerMapping.registerMapping(requestMappingInfo,requestHandler,statement.isRequestBody() ? requestWithRequestBodyHandleMethod : requestHandleMethod);
     }
 
     /**
@@ -141,6 +151,18 @@ public class Configuration implements InitializingBean {
         this.banner = banner;
     }
 
+    public boolean isThrowException() {
+        return throwException;
+    }
+
+    public void setRequestWithRequestBodyHandleMethod(Method requestWithRequestBodyHandleMethod) {
+        this.requestWithRequestBodyHandleMethod = requestWithRequestBodyHandleMethod;
+    }
+
+    public void setThrowException(boolean throwException) {
+        this.throwException = throwException;
+    }
+
     @Override
     public void afterPropertiesSet() {
         if(this.banner){

+ 13 - 0
src/main/java/org/ssssssss/session/Statement.java

@@ -20,6 +20,11 @@ public class Statement {
      */
     private String requestMethod;
 
+    /**
+     * 是否支持requestBody
+     */
+    private boolean requestBody = false;
+
     private List<String> validates = new ArrayList<>();
 
     /**
@@ -66,4 +71,12 @@ public class Statement {
     public void addValidate(String id) {
         this.validates.add(id);
     }
+
+    public boolean isRequestBody() {
+        return requestBody;
+    }
+
+    public void setRequestBody(boolean requestBody) {
+        this.requestBody = requestBody;
+    }
 }

+ 4 - 0
src/main/java/org/ssssssss/utils/S8XMLFileParser.java

@@ -62,6 +62,8 @@ public class S8XMLFileParser {
         for (int i = 0, len = nodeList.getLength(); i < len; i++) {
             Node node = nodeList.item(i);
             FunctionStatement functionStatement = new FunctionStatement();
+            // 设置是否支持RequestBody
+            functionStatement.setRequestBody("true".equalsIgnoreCase(DomUtils.getNodeAttributeValue(node,"request-body")));
             // 设置请求路径
             functionStatement.setRequestMapping(DomUtils.getNodeAttributeValue(node, "request-mapping"));
             // 设置请求方法
@@ -115,6 +117,8 @@ public class S8XMLFileParser {
             SqlStatement sqlStatement = new SqlStatement();
             sqlStatement.setId(DomUtils.getNodeAttributeValue(item, "id"));
             sqlStatement.setXmlStatement(xmlStatement);
+            // 设置是否支持RequestBody
+            sqlStatement.setRequestBody("true".equalsIgnoreCase(DomUtils.getNodeAttributeValue(item,"request-body")));
             String validate = DomUtils.getNodeAttributeValue(item, "validate");
             if (StringUtils.isNotBlank(validate)) {
                 // 支持多个验证