浏览代码

SpringBoot Servlet 集成处理

赵平西 5 年之前
父节点
当前提交
bfd6f3ef21

+ 199 - 0
httpservlet-support/MainServlet.java

@@ -0,0 +1,199 @@
+/*
+ * Copyright 2009 by primedata Corporation. Address:TianChuang Technology Building, CaiHeFang
+ * Road,Haidian District, Beijing
+ *
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of primedata
+ * Corporation ("Confidential Information"). You shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with primedata.
+ */
+package com.primeton.dgs.kernel.core.web;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.sf.json.JSONArray;
+
+
+import com.eos.data.datacontext.UserObject;
+import com.primeton.dgs.kernel.core.common.ActionHelper;
+import com.primeton.dgs.kernel.core.common.ActionResult;
+import com.primeton.dgs.kernel.core.util.ExUtils;
+import com.primeton.licensemanager.checklicense.VerifyHLicenseException;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+/**
+ * mvc主控 Servlet
+ *
+ * @author user
+ * @version 1.0 2006-9-18
+ */
+public class MainServlet extends HttpServlet {
+    private static final long serialVersionUID = 1L;
+
+    private Logger log = LoggerFactory.getLogger(MainServlet.class);
+
+    public static final String ENCODE = "UTF-8";
+
+    String loginPath = "/login.do";
+
+    /**
+     * 无需认证即可访问的白名单
+     */
+    protected Set<String> authWriteList = new HashSet<>();
+
+
+    /**
+     * Initialize global variables
+     */
+    public void init() throws ServletException {
+        log.info("MainServlet init.");
+    }
+
+    /**
+     * Process the HTTP Get request
+     */
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws IOException, ServletException {
+        perform(request, response);
+    }
+
+    /**
+     * Process the HTTP Post request
+     */
+    public void doPost(HttpServletRequest request, HttpServletResponse response)
+            throws IOException, ServletException {
+        perform(request, response);
+    }
+
+    /**
+     * Process the HTTP request
+     */
+    public void perform(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        response.setCharacterEncoding(ENCODE);
+        String next = "";
+        try {
+            String path = request.getServletPath();
+            String name = request.getParameter("invoke");
+
+            // 获取登录信息
+            Object userObject = request.getSession().getAttribute("userObject");
+            // 登录动作,不要拦截
+            //解决当session失效时,请求报错,后台报空指针,页面跳转到非登录页面
+            Object userProfile = request.getSession().getAttribute("com.primeton.dgs.workspace.system.common.UserProfile");
+
+            // 检查是否已经登录
+            if ((null == userObject && null == userProfile) || name == null) {
+                // 未登录,是否在白名单
+                String resourcePath = request.getRequestURI().replaceAll(request.getContextPath(), "");
+                boolean cross = false;
+                PathMatcher matcher = new AntPathMatcher();
+                for (String s : authWriteList) {
+                    cross = matcher.match(s, resourcePath);
+                    if(cross) {
+                        // 一旦通过一个,则进行下一步校验
+                        break;
+                    }
+                }
+
+                // name is null 或者 不通过
+                if(name == null || !cross) {
+                    dispatch(request, response, WebViewer.LONGIN_PAGE);
+                    return;
+                }
+            }
+
+            request.setAttribute("invoke", name);
+            AbstractCommand cmd = CommandFactory.getInstance().getCommand(path);
+
+            cmd.init(request, response, getServletConfig());
+
+            next = cmd.execute();
+            if (null != next) {
+                dispatch(request, response, next);
+            }
+        } catch (VerifyHLicenseException e) {
+            if (isExt(request)) {
+                performOnError(request, response, e);
+                return;
+            }
+            request.setAttribute("javax.servlet.jspException", e);
+            dispatch(request, response, WebViewer.LICENSE_PAGE);
+        } catch (Exception e) {
+            log.error("MainServlet catch an error:", e);
+            if (isExt(request)) {
+                performOnError(request, response, e);
+                return;
+            }
+            request.setAttribute("_CommandExecuteException_",
+                    ExUtils.getMessage(request, e));
+            request.setAttribute("javax.servlet.jspException", e);
+            dispatch(request, response, WebViewer.VIEW_ERROR);
+        }
+
+    }
+
+    public void performOnError(HttpServletRequest request,
+                               HttpServletResponse response, Exception e) throws ServletException,
+            IOException {
+        String msg = ExUtils.getMessage(request, e);
+        ActionResult rs = new ActionResult(false, msg);
+        rs.put("list", new JSONArray());
+        try {
+            if (isReturnXml(request)) {
+                ActionHelper.outputXmlList(response, null, 0, rs);
+            } else {
+                ActionHelper.output(response, rs);
+            }
+        } catch (Exception er) {
+            throw new ServletException(er);
+        }
+    }
+
+    public void dispatch(HttpServletRequest request,
+                          HttpServletResponse response, String page) throws ServletException,
+            IOException {
+        log.info("Command dispath request to: " + page);
+        if (page.toLowerCase().startsWith("http:")
+                || page.toLowerCase().startsWith("https:")) {
+            response.sendRedirect(page);
+        } else {
+            request.getRequestDispatcher(page).forward(request, response);
+        }
+    }
+
+
+    /**
+     * 添加排除
+     * @param s
+     * @return
+     */
+    public boolean addExclude(String s) {
+        if(StringUtils.isBlank(s)) {
+            return false;
+        }
+        return authWriteList.add(StringUtils.trim(s));
+    }
+
+    public static boolean isExt(HttpServletRequest request) {
+        return "Ext".equalsIgnoreCase(request.getHeader("Request-By"));
+    }
+
+    public static boolean isReturnXml(HttpServletRequest request) {
+        return "XML".equalsIgnoreCase(request.getHeader("Response-By"));
+    }
+
+}

+ 164 - 0
httpservlet-support/MetaCubeArthNewSupport.java

@@ -0,0 +1,164 @@
+package com.primeton.dqms.boot.configure;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.net.MediaType;
+import com.primeton.dgs.kernel.core.web.RestMainServlet;
+import lombok.NonNull;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.gocom.coframe.model.User;
+import org.gocom.coframe.sdk.CofContext;
+import org.gocom.coframe.sdk.model.CofUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ *
+ * SpringBoot 下旧的元数据、数据质量架构支持
+ *
+ * <pre>
+ *
+ * Created by zhaopx.
+ * User: zhaopx
+ * Date: 2020/8/7
+ * Time: 10:21
+ *
+ * </pre>
+ *
+ * @author zhaopx
+ */
+
+@WebServlet(name = "NewMetaCubeServlet", urlPatterns = MetaCubeArthNewSupport.API_PREFIX_PATTERN)
+@Component
+public class MetaCubeArthNewSupport extends HttpServlet {
+
+    private Logger log = LoggerFactory.getLogger(MetaCubeArthNewSupport.class);
+
+    /**
+     * 拦截的 API 前缀
+     */
+    public final static String API_PREFIX_PATTERN = "/appsapi/*";
+
+
+    /**
+     * api 前缀
+     */
+    private String apiPrefix = "/" + API_PREFIX_PATTERN.split("/")[1] + "/";
+
+
+    @Value("${coframe.auth.exclude-paths}")
+    private String authExcudes;
+
+
+    /**
+     * 转发 Servlet
+     */
+    final RestMainServlet mainServlet;
+
+
+    public MetaCubeArthNewSupport() {
+        mainServlet = new RestMainServlet();
+    }
+
+    @Override
+    public void init() throws ServletException {
+        String excludes = Optional.ofNullable(authExcudes).orElse("login");
+        String[] splits = excludes.split(",");
+        for (String split : splits) {
+            mainServlet.addExclude(split);
+        }
+        mainServlet.init();
+        log.info("auth exclude urls: " + authExcudes);
+    }
+
+    @Override
+    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+        verifySession(request);
+
+        BufferedReader reader = request.getReader();
+        String header = StringUtils.trimToNull(request.getHeader("Content-Type"));
+        MediaType mediaType = MediaType.parse(Optional.ofNullable(header).orElse("text/html"));
+        if("application".equalsIgnoreCase(mediaType.type()) || "json".equalsIgnoreCase(mediaType.subtype())) {
+            String json = IOUtils.toString(reader);
+            if(StringUtils.isBlank(json)) {
+                json = "{}";
+            }
+            JSONObject jsonObject = JSON.parseObject(json);
+            jsonObject.putAll(parseUrlParams(request.getRequestURI()));
+            mainServlet.perform(request, response, jsonObject);
+            return;
+        }
+        mainServlet.doGet(request, response);
+    }
+
+    @Override
+    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+        verifySession(request);
+
+        BufferedReader reader = request.getReader();
+        String header = StringUtils.trimToNull(request.getHeader("Content-Type"));
+        MediaType mediaType = MediaType.parse(Optional.ofNullable(header).orElse("text/html"));
+        if("application".equalsIgnoreCase(mediaType.type()) || "json".equalsIgnoreCase(mediaType.subtype())) {
+            String json = IOUtils.toString(reader);
+            if(StringUtils.isBlank(json)) {
+                json = "{}";
+            }
+            JSONObject jsonObject = JSON.parseObject(json);
+            jsonObject.putAll(parseUrlParams(request.getRequestURI()));
+            mainServlet.perform(request, response, jsonObject);
+            return;
+        }
+        mainServlet.doPost(request, response);
+    }
+
+
+
+    @NonNull
+    private Map<String, String> parseUrlParams(String url) {
+        final HashMap<String, String> params = new HashMap<>();
+        if(url.contains(apiPrefix)) {
+            String resourceUrl = url.substring(url.indexOf(apiPrefix));
+            String[] splits = resourceUrl.split("/");
+            if(splits.length >= 4){
+                params.put("servletPath", splits[2]);
+                params.put("invoke", splits[3]);
+            }
+        }
+        return params;
+    }
+
+
+    /**
+     * 判断登录,检验 Session。 如果已经登录,则从 session 中获取到登录信息
+     * @param request
+     */
+    private void verifySession(HttpServletRequest request) {
+        CofUser cofUser = (CofUser) CofContext.getContext().get("loginedUser", CofUser.class);
+        if(cofUser == null) {
+            return;
+        }
+
+        Object userObject = request.getSession().getAttribute("userObject");
+        if(userObject == null) {
+            User user = new User();
+            user.setId(cofUser.getId());
+            user.setName(cofUser.getName());
+            user.setTenantId(cofUser.getTenantId());
+            request.getSession().setAttribute("userObject", user);
+        }
+    }
+}

+ 96 - 0
httpservlet-support/MetaCubeHttpServletRequestWrapper.java

@@ -0,0 +1,96 @@
+package com.primeton.dgs.kernel.core.web;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * 元数据旧架构支持 RESTFull API 扩展
+ *
+ *
+ * <pre>
+ *
+ * Created by zhaopx.
+ * User: zhaopx
+ * Date: 2020/9/10
+ * Time: 14:24
+ *
+ * </pre>
+ *
+ * @author zhaopx
+ */
+public class MetaCubeHttpServletRequestWrapper extends HttpServletRequestWrapper {
+
+
+    /**
+     * 元数据部分参数是从 payload 获得的,装饰 RestFull API
+     */
+    protected final Map<String, Object> payloadParameters = new HashMap<>();
+
+
+    /**
+     * Constructs a request object wrapping the given request.
+     *
+     * @param request the {@link HttpServletRequest} to be wrapped.
+     * @throws IllegalArgumentException if the request is null
+     */
+    public MetaCubeHttpServletRequestWrapper(HttpServletRequest request) {
+        super(request);
+    }
+
+
+    public MetaCubeHttpServletRequestWrapper(HttpServletRequest request, Map<String, Object> payloadParameters) {
+        super(request);
+        this.payloadParameters.putAll(payloadParameters);
+    }
+
+    @Override
+    public String getParameter(String name) {
+        String parameter = super.getParameter(name);
+        // 获取参数,如果 form 中为空,则从 payload 中获取
+        return parameter == null ? (String)payloadParameters.get(name) : parameter;
+    }
+
+    @Override
+    public String[] getParameterValues(String name) {
+        String[] parameterValues = super.getParameterValues(name);
+        // 获取参数,如果 form 中为空,则从 payload 中获取
+        return parameterValues == null ? new String[]{ (String)payloadParameters.get(name)} : parameterValues;
+    }
+
+    @Override
+    public Map<String, String[]> getParameterMap() {
+        Map<String, String[]> parameterMap = new HashMap<>(super.getParameterMap());
+
+        // 合并参数
+        for (Map.Entry<String, Object> entry : payloadParameters.entrySet()) {
+            parameterMap.put(entry.getKey(), new String[]{ (String)entry.getValue()});
+        }
+        return parameterMap;
+    }
+
+    @Override
+    public Enumeration<String> getParameterNames() {
+        Set<String> vector = new HashSet();
+        // form 参数
+        Enumeration<String> parameterNames = super.getParameterNames();
+        while (parameterNames.hasMoreElements()) {
+            vector.add(parameterNames.nextElement());
+        }
+
+        // payload 参数
+        for (String s : payloadParameters.keySet()) {
+            vector.add(s);
+        }
+
+        // 构造一次性返回
+        return Collections.enumeration(vector);
+    }
+}

+ 109 - 0
httpservlet-support/RestMainServlet.java

@@ -0,0 +1,109 @@
+/*
+ * Copyright 2009 by primedata Corporation. Address:TianChuang Technology Building, CaiHeFang
+ * Road,Haidian District, Beijing
+ *
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of primedata
+ * Corporation ("Confidential Information"). You shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with primedata.
+ */
+package com.primeton.dgs.kernel.core.web;
+
+import com.primeton.dgs.kernel.core.util.ExUtils;
+import com.primeton.licensemanager.checklicense.VerifyHLicenseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * mvc主控 Servlet, REstFull Api 支持
+ *
+ * @author zhaopx
+ * @version 7.1.0 2020-9-10
+ */
+public class RestMainServlet extends MainServlet {
+    private static final long serialVersionUID = 1L;
+
+    private Logger log = LoggerFactory.getLogger(RestMainServlet.class);
+
+    /**
+     * Process the HTTP request
+     */
+    public void perform(HttpServletRequest request, HttpServletResponse response, Map<String, Object> payload)
+            throws ServletException, IOException {
+        response.setCharacterEncoding(ENCODE);
+        String next = "";
+        try {
+            String path = payload.get("servletPath") + ".do";
+            String name = (String) payload.get("invoke");
+
+            // 获取登录信息
+            Object userObject = request.getSession().getAttribute("userObject");
+            //解决当session失效时,请求报错,后台报空指针,页面跳转到非登录页面
+            Object userProfile = request.getSession().getAttribute("com.primeton.dgs.workspace.system.common.UserProfile");
+            // 检查是否已经登录
+            if ((null == userObject && null == userProfile) || name == null) {
+                // 未登录,是否在白名单
+                String resourcePath = request.getRequestURI().replaceAll(request.getContextPath(), "");
+                boolean cross = false;
+                PathMatcher matcher = new AntPathMatcher();
+                for (String s : authWriteList) {
+                    cross = matcher.match(s, resourcePath);
+                    if(cross) {
+                        // 一旦通过一个,则进行下一步校验
+                        break;
+                    }
+                }
+
+                // name is null 或者 不通过
+                if(name == null || !cross) {
+                    dispatch(request, response, WebViewer.LONGIN_PAGE);
+                    return;
+                }
+            }
+
+            // 要执行的函数
+            request.setAttribute("invoke", name);
+
+            // 合并参数
+            MetaCubeHttpServletRequestWrapper requestWrapper = new MetaCubeHttpServletRequestWrapper(request, payload);
+
+            //获取 bean
+            AbstractCommand cmd = CommandFactory.getInstance().getCommand(path);
+            cmd.init(requestWrapper, response, getServletConfig());
+
+            next = cmd.execute();
+            if (null != next) {
+                dispatch(requestWrapper, response, next);
+            }
+        } catch (VerifyHLicenseException e) {
+            if (isExt(request)) {
+                performOnError(request, response, e);
+                return;
+            }
+            request.setAttribute("javax.servlet.jspException", e);
+            dispatch(request, response, WebViewer.LICENSE_PAGE);
+        } catch (Exception e) {
+            log.error("MainServlet catch an error:", e);
+            if (isExt(request)) {
+                performOnError(request, response, e);
+                return;
+            }
+            request.setAttribute("_CommandExecuteException_",
+                    ExUtils.getMessage(request, e));
+            request.setAttribute("javax.servlet.jspException", e);
+            dispatch(request, response, WebViewer.VIEW_ERROR);
+        }
+
+    }
+
+}

+ 34 - 22
swagger-support/SwaggerExtentionSupport.java

@@ -1,31 +1,26 @@
 package com.primeton.dgs.kernel.core.configure;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
 import com.google.common.net.MediaType;
 import com.primeton.dgs.kernel.core.web.AppBaseDispatchCommand;
-import io.swagger.models.Path;
-import io.swagger.models.Response;
-import io.swagger.models.Swagger;
 import org.apache.commons.lang.StringUtils;
-import org.springframework.context.ApplicationContext;
-import org.springframework.http.HttpMethod;
-import springfox.documentation.builders.ResponseMessageBuilder;
-import springfox.documentation.schema.ModelRef;
-import springfox.documentation.service.Operation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.http.HttpMethod;
 import org.springframework.stereotype.Repository;
+import springfox.documentation.builders.ResponseMessageBuilder;
+import springfox.documentation.schema.ModelRef;
 import springfox.documentation.service.ApiDescription;
 import springfox.documentation.service.ApiListing;
 import springfox.documentation.service.Documentation;
+import springfox.documentation.service.Operation;
+import springfox.documentation.service.Parameter;
 import springfox.documentation.service.ResponseMessage;
 import springfox.documentation.service.Tag;
 import springfox.documentation.spring.web.DocumentationCache;
@@ -37,11 +32,10 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
-import java.util.TreeSet;
 
 /**
  *
@@ -164,11 +158,31 @@ public class SwaggerExtentionSupport implements ApplicationListener<ContextRefre
         tags.add(tag);
 
         // 注意 position,必须是不重复的值
+        ArrayList<Parameter> parameters = new ArrayList<>();
+        /*
+        暂时先不要参数
+        Parameter parameter = new Parameter(
+                "invoke",
+                "Invoke Method",
+                methodName,
+                true,
+                false,
+                false,
+                new ModelRef("string"),
+                null, null,
+                "string","", false, null, null, 0, null,
+                ArrayListMultimap.create(),
+                Collections.emptyList()
+        );
+        parameters.add(parameter);
+         */
+
+        /*
         Operation operaGet = new Operation(
                 HttpMethod.GET,
                 "do exec " + optGroup + "." + methodName,
                 "",
-                new ModelRef("ResponseCode"),
+                new ModelRef("string"),
                 optId+"UsingGET",
                 0,
                 Sets.newHashSet(tag.getName()),
@@ -176,20 +190,20 @@ public class SwaggerExtentionSupport implements ApplicationListener<ContextRefre
                 Sets.newHashSet(MediaType.create("application", "json").toString()),
                 new HashSet<>(),
                 new ArrayList<>(),
-                new ArrayList<>(),
+                parameters,
                 Sets.newHashSet(v200, v401, v403, v404),
                 "",
                 false,
                 new ArrayList<>()
         );
+         */
 
         // Operation 只需要 tag name,他决定了该 api 在 Swagger 上挂载的tag
-        /*
         Operation operaPost = new Operation(
                 HttpMethod.POST,
                 "do exec " + optGroup + "." + methodName,
                 "",
-                new ModelRef("ResponseCode"),
+                new ModelRef("string"),
                 optId+"UsingPOST",
                 0,
                 Sets.newHashSet(tag.getName()),
@@ -197,18 +211,16 @@ public class SwaggerExtentionSupport implements ApplicationListener<ContextRefre
                 Sets.newHashSet(MediaType.create("application", "json").toString()),
                 new HashSet<>(),
                 new ArrayList<>(),
-                new ArrayList<>(),
+                parameters,
                 Sets.newHashSet(v200, v401, v403, v404),
                 "",
                 false,
                 new ArrayList<>()
         );
-         */
 
-        operations.add(operaGet);
-        //operations.add(operaPost);
+        operations.add(operaPost);
 
-        String url = "/" + beanName + "?invoke=" + methodName;
+        String url = "/appsapi/" + optGroup + "/" + methodName;
         apis1.add(new ApiDescription(groupName,
                 url,
                 beanName+"." + methodName,