Apache Camel - 3 - Camel小栗子(HTTP)

Camel 发布HTTP

Apache Camel相关代码已经上传GitHub,需要的自取:GitHub - Apache Camel 完整Demo

如果觉得还行,麻烦点个Star

 

在没有使用Camel之前,我们使用JDK 自带的HttpServer来发布Http服务。

具体的代码不看了,我们看下发布Http服务相关的类有多少吧...

很多是吧...

这里面还要写配置文件,配置上下文接口和接口实现类...实在是麻烦....

再来看看使用Camel,是怎么发布HTTP服务的...

Apache Camel 发布Http服务 完整代码/工程Demo 我上传了...

现在优快云下载必须要积分了...以前我都是0积分的,方便积分不多的童鞋...哎优快云变了...

Apache Camel Http服务 Demo样例

代码一:

package com.test.camel.helloworld;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.ModelCamelContext;
import org.apache.log4j.PropertyConfigurator;

/**
* 郑重其事的写下 helloworld for Apache Camel
*/
public class HelloWorld extends RouteBuilder {

	public static void main(String[] args) throws Exception {

	PropertyConfigurator.configure("./conf/log4j.properties");
	PropertyConfigurator.configureAndWatch("./conf/log4j.properties", 1000);

	// 这是camel上下文对象,整个路由的驱动全靠它了。
	ModelCamelContext camelContext = new DefaultCamelContext();

	// 启动route
	camelContext.start();

	// 将我们编排的一个完整消息路由过程,加入到上下文中
	camelContext.addRoutes(new HelloWorld());

	/**
	 * ==========================<br>
	 * 为什么我们先启动一个Camel服务 再使用addRoutes添加编排好的路由呢?<br>
	 * 这是为了告诉各位读者,Apache Camel支持动态加载/卸载编排的路由 这很重要,因为后续设计的Broker需要依赖这种能力<br>
	 * ==========================<br>
	 */

	// 通用没有具体业务意义的代码,只是为了保证主线程不退出
	synchronized (HelloWorld.class) {
			HelloWorld.class.wait();
	}
	}

	@Override
	public void configure() throws Exception {
			// 在本代码段之下随后的说明中,会详细说明这个构造的含义
			from("jetty:http://0.0.0.0:8282/doHelloWorld").process(new HttpProcessor()).to("log:helloworld?showExchangeId=true");
	}

}

代码二:

package com.test.camel.helloworld;

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

import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.http.common.HttpMessage;
import org.apache.commons.io.IOUtils;

/**
* 这个处理器用来完成输入的json格式的转换
* 
*/
public class HttpProcessor implements Processor {

	@Override
	public void process(Exchange exchange) throws Exception {
			// 因为很明确消息格式是http的,所以才使用这个类
			// 否则还是建议使用org.apache.camel.Message这个抽象接口
			HttpMessage message = (HttpMessage) exchange.getIn();
			InputStream bodyStream = (InputStream) message.getBody();
			String inputContext = this.analysisMessage(bodyStream);
			bodyStream.close();

	// 存入到exchange的out区域
	if (exchange.getPattern() == ExchangePattern.InOut) {
			Message outMessage = exchange.getOut();
			outMessage.setBody(inputContext + " || out");
//			System.out.println(outMessage.getBody());
	}
	}

	/**
	 * 从stream中分析字符串内容
	 * 
	 * @param bodyStream
	 * @return
	 */
	private String analysisMessage(InputStream bodyStream) throws IOException {

	String responseStr = IOUtils.toString(bodyStream, "UTF-8");

//		System.out.println(responseStr);

	return responseStr;
	}
}

下面这个是以前测试HTTP服务的代码,直接拿来用了..

代码三:

package com.test.client.http;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;

public class HttpClient {

	public static final String CODEFORMAT = "UTF-8";

	public static String doPost(String requestBody, int timeout, HttpURLConnection http) throws Exception {
		String retResult = "";
		try {
			// 设置是否从HttpURLConnection读入 ,默认是true
			http.setDoInput(true);
			// post请求的时候需要将DoOutput 设置成true 参数要放在http正文内,因此需要设为true ,默认是false
			http.setDoOutput(true);
			// post请求UseCaches 设置成false 不能设置缓存
			http.setUseCaches(false);
			// 连接主机超时时间
			http.setConnectTimeout(timeout);
			// 从主机读取数据超时 (都是毫秒)
			http.setReadTimeout(timeout);
			// 默认是get
			http.setRequestMethod("POST");
			http.setRequestProperty("accept", "*/*");
			http.setRequestProperty("connection", "Keep-Alive");
			http.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 参数设置完成之后进行连接
			http.connect();
			OutputStreamWriter osw = new OutputStreamWriter(http.getOutputStream(), Charset.forName("UTF-8"));
			osw.write(requestBody);
			osw.flush();
			osw.close();
			if (http.getResponseCode() == 200) {
					BufferedReader in = new BufferedReader(new InputStreamReader(http.getInputStream(), Charset.forName("UTF-8")));
					String inputLine;
					while ((inputLine = in.readLine()) != null) {
							retResult += inputLine;
					}
					in.close();
			} else {
					throw new Exception("the http.getResponseCode() is " + http.getResponseCode());
			}
		} catch (Exception e) {
				e.printStackTrace();
		} finally {
				if (http != null) {
						http.disconnect();
						http = null;
				}
		}
			return retResult;
	}
}

代码四:

package com.test.client.http;

import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;

public class TestClient {

	public static void main(String[] args) {
		URL url = null;
		HttpURLConnection http = null;

	try {

	url = new URL("http://0.0.0.0:8282/doHelloWorld");

	for (int i = 0; i < 1; i++) {
			System.out.println("http post start !!!");
			Long startTime = System.currentTimeMillis();

	http = (HttpURLConnection) url.openConnection();

	// ************************************************************
	JSONObject authorityJson = new JSONObject();
	authorityJson.put("userid", "222222222222222"); // 用户身份证号码
	authorityJson.put("username", "VIP_USER");// 用户姓名
	authorityJson.put("userdept", "VIP");// 用户单位

	JSONObject queryInfoJson = new JSONObject();
	queryInfoJson.put("source", "60155");// 测试用
	queryInfoJson.put("condition", "FIRSTKEY = '320103671118051'");
	queryInfoJson.put("starttime", "");
	queryInfoJson.put("endtime", "");

	JSONObject requestJson = new JSONObject();
	requestJson.put("authority", authorityJson);
	requestJson.put("queryInfo", queryInfoJson);
	// ************************************************************

	StringBuffer sb = new StringBuffer();
	sb.append(requestJson.toString());

	String result = HttpClient.doPost(sb.toString(), 30000000, http);

	System.out.println("http post end cost :" + (System.currentTimeMillis() - startTime) + "ms");
	System.out.println(result);

	Thread.sleep(500);
	}

	} catch (Exception e) {
			e.printStackTrace();
	}

	}
}

代码五:

 

#####输出到控制台#####
log4j.rootLogger=DEBUG,CONSOLE,ARKSERVICES
log4j.addivity.org.apache=true
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d %p %l - %m%n

#####输出到文件#####
log4j.appender.ARKSERVICES=org.apache.log4j.RollingFileAppender
log4j.appender.ARKSERVICES.File=../log/camel-test.log
log4j.appender.ARKSERVICES.Threshold=DEBUG
log4j.appender.ARKSERVICES.MaxBackupIndex=5
log4j.appender.ARKSERVICES.MaxFileSize=100MB
log4j.appender.ARKSERVICES.layout=org.apache.log4j.PatternLayout
log4j.appender.ARKSERVICES.layout.ConversionPattern=%d %t %p %l - %m%n

log4j.logger.org.eclipse.jetty=OFF

上述代码是一个完整可运行的测试样例,可以直接拿来使用。

它展示了一个简单的可以实际运行的消息路由规则:

首先from语句中填写的"jetty:http://0.0.0.0:8282/doHelloWorld",表示这个编排好的路由的消息入口。

它使用HTTP传输协议,访问本物理节点上任何IP(127.0.0.0或192.168.1.1),在端口8282上的请求,都可以将HTTP携带的消息传入这个路由。

接下来消息会在HttpProcessor这个自定义的处理器中进行转换。

为了看清原理,HttpProcessor中的消息转换很简单,在HTTP传入的JSON字符串的末尾,加上一个" ||out",并进行输出。

Apache Camel中自带了很多的处理器,并且可以自行实现Processor接口来实现自己的处理逻辑。

最后,消息被传输到一个endPoint控制端点,这个endPoint控制端点的URI描述(log:helloworld?showExchangeId=true),表明它是一个Log4j的实现,

所以消息最终会以Log日志的方式输出到控制台上,到此,这个编排的路由就执行完了。

 

Apache Camel Endpoint同时发布多个服务

好奇,测试一下,Camel能不能同时发布多个服务。

代码一:

package com.camel.directcamel2;

import java.io.InputStream;

import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.http.common.HttpMessage;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.ModelCamelContext;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.PropertyConfigurator;

/**
* 模拟同时,发布两个http服务,不同的url,处理不同的业务逻辑
* 
* @author CYX
* @time 2017年12月15日下午3:09:27
*/
public class DirectCamel {

	public static void main(String[] args) throws Exception {

	// 加载日志
	PropertyConfigurator.configure("./conf/log4j.properties");
	PropertyConfigurator.configureAndWatch("./conf/log4j.properties", 1000);

	// 这是camel上下文对象,整个路由的驱动全靠它了。
	ModelCamelContext camelContext = new DefaultCamelContext();

	// 启动route
	camelContext.start();

	// 首先将两个完整有效的路由注册到Camel服务中
	camelContext.addRoutes(new RouteBuilder() {

	@Override
	public void configure() throws Exception {

	// 连接路由:DirectRouteB
	from("jetty:http://0.0.0.0:8282/directCamelaa").process(new Processor() {

	@Override
	public void process(Exchange exchange) throws Exception {

	// 因为很明确消息格式是http的,所以才使用这个类
	// 否则还是建议使用org.apache.camel.Message这个抽象接口
	HttpMessage message = (HttpMessage) exchange.getIn();
	InputStream bodyStream = (InputStream) message.getBody();
	String inputContext = IOUtils.toString(bodyStream, "UTF-8");

	System.out.println("A inputContext -- " + inputContext);

	bodyStream.close();

	// 存入到exchange的out区域
	if (exchange.getPattern() == ExchangePattern.InOut) {
			Message outMessage = exchange.getOut();
			outMessage.setBody(inputContext + " || aaa");
	}

	}
	}).to("log:directRouteARouteBuilder?showExchangeId=true");

	}
	});

	camelContext.addRoutes(new RouteBuilder() {

	@Override
	public void configure() throws Exception {
			from("jetty:http://0.0.0.0:8282/directCamelbb").process(new Processor() {

	@Override
	public void process(Exchange exchange) throws Exception {

	// 因为很明确消息格式是http的,所以才使用这个类
	// 否则还是建议使用org.apache.camel.Message这个抽象接口
	HttpMessage message = (HttpMessage) exchange.getIn();
	InputStream bodyStream = (InputStream) message.getBody();
	String inputContext = IOUtils.toString(bodyStream, "UTF-8");

	System.out.println("B inputContext  -- " + inputContext);

	// 存入到exchange的out区域
	if (exchange.getPattern() == ExchangePattern.InOut) {
			Message outMessage = exchange.getOut();
			outMessage.setBody(bodyStream + " || outbbbb");
	}

	}
	}).to("log:directRouteBRouteBuilder?showExchangeId=true");
	}
	});

	// 通用没有具体业务意义的代码,只是为了保证主线程不退出
	synchronized (DirectCamel.class) {
			DirectCamel.class.wait();
	}

	}
}

测试、代码二:

 

package com.test.client.directcamel2;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;

public class HttpClient {

	public static final String CODEFORMAT = "UTF-8";

	public static String doPost(String requestBody, int timeout, HttpURLConnection http) throws Exception {
		String retResult = "";
		try {
			// 设置是否从HttpURLConnection读入 ,默认是true
			http.setDoInput(true);
			// post请求的时候需要将DoOutput 设置成true 参数要放在http正文内,因此需要设为true ,默认是false
			http.setDoOutput(true);
			// post请求UseCaches 设置成false 不能设置缓存
			http.setUseCaches(false);
			// 连接主机超时时间
			http.setConnectTimeout(timeout);
			// 从主机读取数据超时 (都是毫秒)
			http.setReadTimeout(timeout);
			// 默认是get
			http.setRequestMethod("POST");
			http.setRequestProperty("accept", "*/*");
			http.setRequestProperty("connection", "Keep-Alive");
			http.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 参数设置完成之后进行连接
			http.connect();
			OutputStreamWriter osw = new OutputStreamWriter(http.getOutputStream(), Charset.forName("UTF-8"));
			osw.write(requestBody);
			osw.flush();
			osw.close();
			if (http.getResponseCode() == 200) {
					BufferedReader in = new BufferedReader(new InputStreamReader(http.getInputStream(), Charset.forName("UTF-8")));
					String inputLine;
					while ((inputLine = in.readLine()) != null) {
							retResult += inputLine;
					}
					in.close();
			} else {
					throw new Exception("the http.getResponseCode() is " + http.getResponseCode());
			}
		} catch (Exception e) {
				e.printStackTrace();
		} finally {
				if (http != null) {
						http.disconnect();
						http = null;
				}
		}
			return retResult;
	}
}

测试、代码三:

 

package com.test.client.directcamel2;

import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;

public class TestClient {

	public static void main(String[] args) {
			URL url = null;
			HttpURLConnection http = null;

	try {

//			url = new URL("http://0.0.0.0:8282/directCamelaa");
	url = new URL("http://0.0.0.0:8282/directCamelbb");

	for (int i = 0; i < 1; i++) {
			System.out.println("http post start !!!");
			Long startTime = System.currentTimeMillis();

	http = (HttpURLConnection) url.openConnection();

	// ************************************************************
	JSONObject authorityJson = new JSONObject();
	authorityJson.put("userid", "222222222222222"); // 用户身份证号码
	authorityJson.put("username", "VIP_USER");// 用户姓名
	authorityJson.put("userdept", "VIP");// 用户单位

	JSONObject queryInfoJson = new JSONObject();
	queryInfoJson.put("source", "60155");// 测试用
	queryInfoJson.put("condition", "FIRSTKEY = '320103671118051'");
	queryInfoJson.put("starttime", "");
	queryInfoJson.put("endtime", "");

	JSONObject requestJson = new JSONObject();
	requestJson.put("authority", authorityJson);
	requestJson.put("queryInfo", queryInfoJson);
	// ************************************************************

	StringBuffer sb = new StringBuffer();
	sb.append(requestJson.toString());
	System.out.println(sb.toString());

	String result = HttpClient.doPost(sb.toString(), 30000000, http);

	System.out.println("http post end cost :" + (System.currentTimeMillis() - startTime) + "ms");
	System.out.println(result);

	Thread.sleep(500);
	}

	} catch (Exception e) {
			e.printStackTrace();
	}

	}
}

切换两个URL之后的输出结果:

 

A inputContext -- {"authority":{"userdept":"VIP","userid":"222222222222222","username":"VIP_USER"},"queryInfo":{"condition":"FIRSTKEY = '320103671118051'","endtime":"","source":"60155","starttime":""}}

[2017-12-15 17:09:44,710] [qtp192428201-19] [DEBUG] [org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)] - >>>> log://directRouteARouteBuilder?showExchangeId=true Exchange[ID-CYX-49644-1513328973453-0-1]

[2017-12-15 17:09:44,725] [qtp192428201-19] [INFO] [org.apache.camel.util.CamelLogger.log(CamelLogger.java:159)] - Exchange[Id: ID-CYX-49644-1513328973453-0-1, ExchangePattern: InOut, BodyType: String, Body: {"authority":{"userdept":"VIP","userid":"222222222222222","username":"VIP_USER"},"queryInfo":{"condition":"FIRSTKEY = '320103671118051'","endtime":"","source":"60155","starttime":""}} || aaa]

[2017-12-15 17:09:44,725] [qtp192428201-19] [DEBUG] [org.apache.camel.http.common.DefaultHttpBinding.doWriteDirectResponse(DefaultHttpBinding.java:489)] - Streaming response in chunked mode with buffer size 32768

 

 

B inputContext  -- {"authority":{"userdept":"VIP","userid":"222222222222222","username":"VIP_USER"},"queryInfo":{"condition":"FIRSTKEY = '320103671118051'","endtime":"","source":"60155","starttime":""}}

[2017-12-15 17:10:22,355] [qtp192428201-21] [DEBUG] [org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)] - >>>> log://directRouteBRouteBuilder?showExchangeId=true Exchange[ID-CYX-49644-1513328973453-0-4]

[2017-12-15 17:10:22,355] [qtp192428201-21] [INFO] [org.apache.camel.util.CamelLogger.log(CamelLogger.java:159)] - Exchange[Id: ID-CYX-49644-1513328973453-0-4, ExchangePattern: InOut, BodyType: String, Body: org.apache.camel.converter.stream.InputStreamCache@569e9cb3 || outbbbb]

[2017-12-15 17:10:22,355] [qtp192428201-21] [DEBUG] [org.apache.camel.http.common.DefaultHttpBinding.doWriteDirectResponse(DefaultHttpBinding.java:489)] - Streaming response in chunked mode with buffer size 32768

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值