All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.logicbus.backend.server.http.MessageRouterServletHandler Maven / Gradle / Ivy

There is a newer version: 1.6.17
Show newest version
package com.logicbus.backend.server.http;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alogic.matcher.CommonMatcher;
import com.alogic.matcher.MatcherFactory;
import com.anysoft.util.*;
import com.anysoft.util.resource.ResourceFactory;
import com.anysoft.webloader.HttpClientTool;
import com.google.re2j.Matcher;
import com.google.re2j.Pattern;
import com.logicbus.backend.IpAndServiceAccessController;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.anysoft.webloader.ServletConfigProperties;
import com.anysoft.webloader.ServletHandler;
import com.logicbus.backend.AccessController;
import com.logicbus.backend.DefaultNormalizer;
import com.logicbus.backend.Normalizer;
import com.logicbus.backend.server.MessageRouter;
import com.logicbus.models.catalog.Path;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * 基于anyWebLoader的ServletHandler
 * 
 * @author duanyy
 * 
 * @version 1.0.5 [20140412 duanyy] 
* - 修改消息传递模型。
* * @version 1.0.7 [20140418 duanyy]
* - 增加全局序列号功能,从Http头的GlobalSerial变量获取前端传入的全局序列号 * * @version 1.2.1 [20140614 duanyy]
* - 支持跨域服务调用 * * @version 1.2.6 [20140807 duanyy]
* - ServantPool和ServantFactory插件化 * * @version 1.2.7.2 [20140910 duanyy]
* - Normalizer降级为Servlet级别对象 * * @version 1.3.0.1 [20141031 duanyy]
* - 解决问题:框架截获了post方式的body数据,导致post过来的form数据无法获取 * * @version 1.4.0 [20141117 duanyy]
* - 将MessageDoc和Context进行合并整合
* * @version 1.6.1.2 [20141118 duanyy]
* - 支持HttpContext的数据截取,通过Servlet的变量intercept.mode来控制
* * @version 1.6.3.28 [20150708 duanyy]
* - 允许设置为缓存模式
* * @version 1.6.4.8 [20151013 duanyy]
* - CORS成了可选配置
* * @version 1.6.5.6 [20160523 duanyy]
* - 在MessageRouter中提前写出报文
* * @version 1.6.7.9 [20170201 duanyy]
* - 采用SLF4j日志框架输出日志
* * @version 1.6.8.6 [20170410 duanyy]
* - 增加Options方法的实现
* * @version 1.6.9.8 [20170821 duanyy]
* - 优化代码
* * @version 1.6.11.12 [20170123 duanyy]
* - http响应的缓存属性改成由服务来个性化控制
* * @version 1.6.12.8 [20181121 duanyy]
* - 关闭缺省的cors支持
* * @version 1.6.12.11 [20181206 duanyy]
* - 可配置是否支持options方法
* * @version 1.6.13.30 [20210106 duanyy]
* - CORS支持改为定向域名支持
* * @version 1.6.13.31 [20210108 duanyy]
* - 支持对Origin中域名的解析
* * @version 1.6.14.6 [20210415 duanyy]
* - 可通过配置文件进行配置
*/ public class MessageRouterServletHandler implements ServletHandler,XMLConfigurable, Configurable { /** * 访问控制器 */ protected AccessController ac = null; /** * 路径标准化 */ protected Normalizer normalizer = null; /** * 是否开启拦截模式 */ protected boolean interceptMode = false; /** * a logger of log4j */ protected static Logger LOG = LoggerFactory.getLogger(MessageRouterServletHandler.class); protected static final String DEFAULT = "java:///com/logicbus/backend/servant.entry.xml#" + MessageRouterServletHandler.class.getName(); /** * 是否已经获取服务器信息 */ protected static boolean getServerInfo = false; /** * 编码 */ protected static String encoding = "utf-8"; protected String methodAllow = "GET,PUT,POST"; protected boolean corsSupport = false; protected boolean optionSupport = true; protected CommonMatcher corsMatcher = null; protected HttpClientTool clientTool = null; /** * 用来提取Origin中域名的正则表达式 */ protected static Pattern pattern = Pattern.compile("(\\w+):\\/\\/([^/:]+)(?::(\\d*))?([^#\\?]*)"); @Override public void init(ServletConfig servletConfig) throws ServletException { ServletConfigProperties props = new ServletConfigProperties(servletConfig); String master = PropertiesConstants.getString(props, "servant.entry.master", DEFAULT); String secondary = PropertiesConstants.getString(props, "servant.entry.secondary", DEFAULT); ResourceFactory rf = Settings.getResourceFactory(); InputStream in = null; try { in = rf.load(master, secondary, null); Document doc = XmlTools.loadFromInputStream(in); if (doc != null){ configure(doc.getDocumentElement(), props); } }catch (Exception ex){ LOG.error("Can not init servant entry with file : " + master); }finally{ IOTools.close(in); } } @Override public void configure(Properties props) { encoding = PropertiesConstants.getString(props,"http.encoding", encoding); corsSupport = PropertiesConstants.getBoolean(props, "http.cors", corsSupport); optionSupport = PropertiesConstants.getBoolean(props, "http.option", optionSupport); methodAllow = PropertiesConstants.getString(props, "http.method.allow", methodAllow); interceptMode = PropertiesConstants.getBoolean(props, "intercept.mode", interceptMode); corsMatcher = MatcherFactory.getMatcher(PropertiesConstants.getString(props,"http.cors.matcher","(wildcard)*"),props); if (normalizer == null) { String normalizerClass = PropertiesConstants.getString(props, "normalizer", DefaultNormalizer.class.getName()); LOG.info("Normalizer is initializing,module:" + normalizerClass); try { Normalizer.TheFactory ncf = new Normalizer.TheFactory( Settings.getClassLoader()); normalizer = ncf.newInstance(normalizerClass, props); } catch (Throwable t) { normalizer = new DefaultNormalizer(props); LOG.error("Failed to initialize Normalizer.Using default:" + DefaultNormalizer.class.getName()); } } clientTool = Settings.getToolkit(HttpClientTool.class); if (ac == null) { ac = (AccessController) Settings.get("accessController"); } } @Override public void configure(Element e, Properties p) { XmlElementProperties props = new XmlElementProperties(e,p); Element elem = XmlTools.getFirstElementByPath(e,"normalizer"); if (elem != null){ try { Normalizer.TheFactory ncf = new Normalizer.TheFactory(Settings.getClassLoader()); normalizer = ncf.newInstance(elem,props,"module",DefaultNormalizer.class.getName()); } catch (Throwable t) { LOG.error("Failed to initialize Normalizer:" + XmlTools.node2String(elem)); LOG.error(ExceptionUtils.getStackTrace(t)); } } elem = XmlTools.getFirstElementByPath(e,"ac"); if (elem != null){ AccessController.TheFactory f = new AccessController.TheFactory(); try { ac = f.newInstance(elem,props,"module", IpAndServiceAccessController.class.getName()); } catch (Throwable t) { LOG.error("Failed to create access controller:" + XmlTools.node2String(elem)); LOG.error(ExceptionUtils.getStackTrace(t)); } } configure(props); } @Override public void doService(HttpServletRequest request, HttpServletResponse response, String method) throws ServletException, IOException { if (!getServerInfo){ Settings settings = Settings.get(); settings.SetValue("server.host", request.getLocalAddr()); settings.SetValue("server.port", String.valueOf(request.getLocalPort())); LOG.info("Get server info:" + settings.GetValue("server.host", "") + ":" + settings.GetValue("server.port","")); getServerInfo = true; } // 1.2.1 duanyy // to support CORS if (corsSupport){ String origin = request.getHeader("Origin"); if (StringUtils.isNotEmpty(origin) && corsMatcher != null){ Matcher matcher = pattern.matcher(origin); String domain = origin; if (matcher.find()){ domain = matcher.group(2); } if (corsMatcher.isMatch(domain)) { clientTool.setResponseHeader(response,"Access-Control-Allow-Origin", origin); clientTool.setResponseHeader(response,"Access-Control-Allow-Credentials", "true"); } } } if (method.equals("options")){ if (optionSupport){ clientTool.setResponseHeader(response,"Allow", methodAllow); }else{ clientTool.sendError(response,HttpServletResponse.SC_NOT_FOUND,"core.e1000:Method options is not supported now."); } }else{ HttpContext ctx = new HttpContext(request,response,encoding,interceptMode); MessageRouter.action(normalizer,request,ctx,ac); } } @Override public void destroy() { } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy