在企业中,往往有很多的Http接口很多的服务,那就需要很多的ip地址或者域名以及端口号了,那是不现实的,就算现实了,对于运维人员和开发人员来说也是很不好的,多起来的时候,最后谁知道哪个域名哪个端口对于的是哪个服务呀,最终还是害惨了自己。
所以,下面,我就介绍一个http转发的实现,我们可以监听一个端口号,对于是这个端口号的所有地址进行一个拦截,然后再统一的转发出去,这样子是不是很靠谱呀,那该如何实现呢??下面来看看这个例子:
一、首先,我们先建立一个blueprint.xml文件,因为这是OSGI环境的桥梁,少不了。
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<bean id="httpDispatchErrorHandleBean" class="jmust.Common.HttpDispatchErrorHandle" />
<bean id="httpDispatchErrorHandle" class="org.apache.camel.builder.DeadLetterChannelBuilder">
<property name="deadLetterUri" value="bean:httpDispatchErrorHandleBean"/>
</bean>
<camelContext id="httpCamelContext" errorHandlerRef="httpDispatchErrorHandle" xmlns="http://camel.apache.org/schema/blueprint">
<restConfiguration bindingMode="auto" component="restlet" port="8888" />
<!-- 拦截所有的请求(timeout = 1分钟) 一个地址支持四种请求 -->
<rest>
<get uri="/">
<to uri="vm:http-dispatch?timeout=18000" />
</get>
<post uri="/">
<to uri="vm:http-dispatch?timeout=18000" />
</post>
<delete uri="/">
<to uri="vm:http-dispatch?timeout=18000" />
</delete>
<head uri="/">
<to uri="vm:http-dispatch?timeout=18000" />
</head>
<put uri="/">
<to uri="vm:http-dispatch?timeout=18000" />
</put>
</rest>
<!-- 通用的http调度处理 -->
<route>
<from uri="vm:http-dispatch" />
<to uri="log:httpDispatchProcessor?showAll=true;&multiline=true" />
<to uri="bean:httpDispatchProcessor" />
</route>
<!-- 请求地址 -->
<route>
<from uri="direct-vm:/demo/test" />
<to uri="bean:httpTestProcessor"/>
</route>
<!-- 请求地址 -->
<route>
<from uri="direct-vm:/demo/test1"/>
<to uri="bean:httpTest1Processor"/>
</route>
</camelContext>
<bean id="httpProducerTemplate" class="org.apache.camel.impl.DefaultProducerTemplate" init-method="start">
<argument ref="httpCamelContext" />
</bean>
<!-- 服務註冊 -->
<bean id="httpDispatchProcessor" class="jmust.Common.HttpDispatchProcessor">
<property name="producerTemplate" ref="httpProducerTemplate" />
</bean>
<bean id="httpTestProcessor" class="jmust.Common.TestProcessor">
</bean>
<bean id="httpTest1Processor" class="jmust.Common.Test1Processor">
</bean>
</blueprint>
二、增加一个接收转发请求的Processor,让它去处理所有的请求,最终返回固定ip、端口号
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.restlet.RestletConstants;
import org.restlet.engine.adapter.HttpRequest;
import jmust.Common.Utils.ExchangeUtil;
import jmust.Common.Utils.PathUtil;
/**
* 监听特定端口转发
* @author lvkun
*
*/
public class HttpDispatchProcessor implements Processor{
private CamelContext camelContext ;
private ProducerTemplate producerTemplate;
public void process(Exchange exchange) throws Exception {
HttpRequest request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, HttpRequest.class);
String contextPath = PathUtil.getAbsPath(request.getHttpCall().getRequestUri());
ExchangeUtil.sendExchage(camelContext, producerTemplate, exchange, contextPath);
}
public CamelContext getCamelContext() {
return camelContext;
}
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}
public ProducerTemplate getProducerTemplate() {
return producerTemplate;
}
public void setProducerTemplate(ProducerTemplate producerTemplate) {
this.producerTemplate = producerTemplate;
}
}
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.ProducerTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Exchange公用工具
* @author lvkun
*
*/
public class ExchangeUtil {
private static final String DEST_COMPONENT = "direct-vm";
private static final String FAVICON = "/favicon.ico";
private static final Logger log = LoggerFactory.getLogger(ExchangeUtil.class);
public static void sendExchage(CamelContext camelContext,ProducerTemplate producerTemplate,Exchange exchange,String contextPath){
if(!FAVICON.equals(contextPath)&&!"/".equals(contextPath))
{
String route = DEST_COMPONENT + ":" +contextPath;
log.info("redirect endpoint {}", route);
Exchange exch = producerTemplate.send(route, exchange);
if(exch != null && exch.getOut() != null){
exchange.getOut().setBody(exch.getOut().getBody());
}
}
else if(FAVICON.equals(contextPath))
{
exchange.getOut().setBody("");
}
}
}
四、封装获取相对路径的工具
import javax.servlet.http.HttpServletRequest;
/**
* 获取路径方法
* @author lvkun
*
*/
public class PathUtil {
/**
* 获取相对路径
* @param contextPath
* @return
*/
public static String getAbsPath(String contextPath)
{
int index = contextPath.indexOf('?');
if(index > -1)
{
return contextPath.substring(0, index);
}
return contextPath;
}
/**
* 获取方式
* @param request
* @return
*/
public static String getContentType(HttpServletRequest request){
String contentType = request.getContentType();
if(contentType!=null&&contentType.contains("multipart/form-data")){
contentType = "multipart/form-data";
}else if(contentType!=null&&contentType.contains("text/plain")){
contentType = "text/plain";
}
return contentType;
}
}
jmust.Common.TestProcessor <pre name="code" class="html">jmust.Common.Test1Processor
就不创建了,运用的时候创建,并继承Camel的Processor即可。
完毕!