项目参考:GitHub - dk2k/camel-as2-usage
as2原理
关于as2的原理网络上很多博主前辈已经讲的很透彻了,我就不重复阐述了
pom.xml引用
<dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-starter</artifactId> <version>3.10.0</version> </dependency>
<dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-as2-starter</artifactId> <version>3.10.0</version> </dependency>
接下来要干吗呢?当然是申明server端和client端了
camel server端
package ru.outofrange.as2.route; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.as2.AS2Component; import org.apache.camel.component.as2.AS2Configuration; import org.apache.camel.component.as2.api.AS2CompressionAlgorithm; import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm; import org.apache.camel.component.as2.api.AS2MessageStructure; import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.api.util.AS2Utils; import org.apache.camel.component.as2.internal.AS2ApiName; import org.apache.http.HttpRequest; import org.apache.http.protocol.HttpCoreContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import ru.outofrange.cert.SelfSignedCertLoader; @Component public class AS2ServerRouteBuilder extends RouteBuilder { private static final boolean NEED_SIGNED_ENCRYPTED = true; @Autowired private CamelContext camelContext; @Autowired private SelfSignedCertLoader selfSignedCertLoader; @Value("${as2.version}") private String as2Version; @Value("${camel.server.port}") private Integer serverPortNumber; @Value("${camel.server.uri}") private String as2RequestUri; @Override public void configure() throws Exception { //构建监听接口 final Endpoint as2ServerEndpoint = configureAs2ServerEndpoint(); from(as2ServerEndpoint) .id("as2Server") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { HttpCoreContext context = exchange.getProperty(org.apache.camel.component.as2.internal.AS2Constants.AS2_INTERCHANGE, HttpCoreContext.class); //获取交互内容 if (context != null) { //请求内容 HttpRequest request = context.getRequest(); System.out.println("server接收内容:"+AS2Utils.printMessage(request)); String ediMessage = exchange.getIn().getBody(String.class); System.out.println("server接收报文:"+ediMessage); System.out.println("---------------------------------"); } else { System.out.println("上下文中缺少AS2交换"); } } }) .log("将消息重定向到标准输出:") .to("stream:out"); } /** * 构建as2服务端 * @return * @throws Exception */ private Endpoint configureAs2ServerEndpoint() throws Exception { String methodName = "listen"; //as2Configuration. //服务端配置 AS2Configuration endpointConfiguration = new AS2Configuration(); //端口 endpointConfiguration.setTargetPortNumber(serverPortNumber); //客户端申明 endpointConfiguration.setApiName(AS2ApiName.SERVER); //接口名 endpointConfiguration.setMethodName(methodName); //url申明 endpointConfiguration.setRequestUri(as2RequestUri); //版本号申明 endpointConfiguration.setAs2Version(as2Version); //mdn 回执 // camel as2 server component will send its own hardcoded template anyway endpointConfiguration.setMdnMessageTemplate("my template"); //加密签名 if (NEED_SIGNED_ENCRYPTED) { //加密算法 endpointConfiguration.setSigningAlgorithm(AS2SignatureAlgorithm.SHA1WITHRSA); //设置签名证书链 endpointConfiguration.setSigningCertificateChain(selfSignedCertLoader.getChain()); //设置签名私钥 endpointConfiguration.setSigningPrivateKey(selfSignedCertLoader.getPrivateKey()); //签名接收麦克风算法 endpointConfiguration.setSignedReceiptMicAlgorithms(new String[] {"sha1", "md5"}); //设置加密算法 endpointConfiguration.setEncryptingAlgorithm(AS2EncryptionAlgorithm.DES_EDE3_CBC); //设置加密证书链 endpointConfiguration.setEncryptingCertificateChain(selfSignedCertLoader.getChain()); //设置消息结构 endpointConfiguration.setAs2MessageStructure(AS2MessageStructure.SIGNED_ENCRYPTED); //设置解密私钥 endpointConfiguration.setDecryptingPrivateKey(selfSignedCertLoader.getPrivateKey()); //集合压缩算法 endpointConfiguration.setCompressionAlgorithm(AS2CompressionAlgorithm.ZLIB); } else { endpointConfiguration.setAs2MessageStructure(AS2MessageStructure.PLAIN); } AS2Component as2Component = new AS2Component(); as2Component.setCamelContext(camelContext); as2Component.setConfiguration(endpointConfiguration); //创建as2接口 return as2Component.createEndpoint("as2:server/listen?serverPortNumber={{camel.server.port}}&requestUriPattern={{camel.server.uri}}"); } }
client端
package ru.outofrange.as2.route; import com.sun.istack.ByteArrayDataSource; import org.apache.camel.CamelContext; import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.as2.api.AS2CompressionAlgorithm; import org.apache.camel.component.as2.api.AS2EncryptionAlgorithm; import org.apache.camel.component.as2.api.AS2MessageStructure; import org.apache.camel.component.as2.api.AS2SignatureAlgorithm; import org.apache.camel.component.as2.api.entity.DispositionNotificationMultipartReportEntity; import org.apache.camel.http.common.HttpMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import ru.outofrange.cert.SelfSignedCertLoader; import javax.mail.BodyPart; import javax.mail.Header; import javax.mail.MessagingException; import javax.mail.internet.MimeMultipart; import javax.servlet.http.HttpServletRequest; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Enumeration; @Component public class LocalhostStubAS2ClientRouteBuilder extends RouteBuilder { private static final boolean NEED_SIGNED_ENCRYPTED = true; @Autowired CamelContext camelContext; @Autowired private SelfSignedCertLoader selfSignedCertLoader; @Value("${as2.version}") private String as2Version; @Value("${camel.server.uri}") private String as2RequestUri; @Value("${camel.server.port}") private Integer as2ServerPortNumber; private static org.apache.http.entity.ContentType contentType = org.apache.http.entity.ContentType.create("application/edifact", (Charset) null); @Override public void configure() throws Exception { //触发请求 from("jetty:http://localhost:3500/link") .routeId("as2ClientLocalhost") .process(new Processor() { //信息接收 @Override public void process(Exchange exchange) throws Exception { //获取接收数据 String messageIn = exchange.getIn().getBody(String.class); System.out.println("postman 发送消息: " + messageIn); //清空请求内容 exchange.getIn().reset(); //设置请求内容 exchange.getIn().setBody(messageIn); //设置请求头 exchange.getIn().setHeader("CamelAS2.as2To", "DKtestAS2"); exchange.getIn().setHeader("CamelAS2.as2From", "DKcompanyAS2"); exchange.getIn().setHeader("CamelAS2.as2Version", as2Version); exchange.getIn().setHeader("CamelAS2.ediMessageContentType", contentType); exchange.getIn().setHeader("CamelAS2.server", "DK AS2Client Localhost"); exchange.getIn().setHeader("CamelAS2.subject", "testDK"); exchange.getIn().setHeader("CamelAS2.from", "DKEdi"); exchange.getIn().setHeader("CamelAS2.dispositionNotificationTo", "dk2k@mail.ru"); exchange.getIn().setHeader("CamelAS2.requestUri", as2RequestUri); if (NEED_SIGNED_ENCRYPTED) { exchange.getIn().setHeader("CamelAS2.signingAlgorithm", AS2SignatureAlgorithm.SHA1WITHRSA); exchange.getIn().setHeader("CamelAS2.signingCertificateChain", selfSignedCertLoader.getChain()); exchange.getIn().setHeader("CamelAS2.signingPrivateKey", selfSignedCertLoader.getPrivateKey()); exchange.getIn().setHeader("CamelAS2.signedReceiptMicAlgorithms", new String[] {"sha1", "md5"}); exchange.getIn().setHeader("CamelAS2.encryptingAlgorithm", AS2EncryptionAlgorithm.DES_EDE3_CBC); exchange.getIn().setHeader("CamelAS2.encryptingCertificateChain", selfSignedCertLoader.getChain()); exchange.getIn().setHeader("CamelAS2.decryptingPrivateKey", selfSignedCertLoader.getPrivateKey()); exchange.getIn().setHeader("CamelAS2.as2MessageStructure", AS2MessageStructure.SIGNED_ENCRYPTED); exchange.getIn().setHeader("CamelAS2.compressionAlgorithm", AS2CompressionAlgorithm.ZLIB); } else { exchange.getIn().setHeader("CamelAS2.as2MessageStructure", AS2MessageStructure.PLAIN); } } }) //as2 目标 .to("as2://client/send?targetHostName=localhost" + "&targetPortNumber={{camel.server.port}}" + // http "&inBody=ediMessage" + "&requestUri={{camel.server.uri}}" ) .id("DKAS2senderToLocalhost") .process(new Processor() { //MDN @Override public void process(Exchange exchange) throws Exception { if (exchange.getIn() != null) { try { String messageIn = exchange.getIn().getBody(String.class); System.out.println("Received MDN Message: " + messageIn); processMultipartMessage(exchange.getIn()); } catch (NullPointerException npe) { log.error("NPE caught"); } } else { log.warn("process(): null for MDN"); } } }); } private void processMultipartMessage(Message message) { //判定mdn为http对象 if (message.getBody() instanceof DispositionNotificationMultipartReportEntity) { DispositionNotificationMultipartReportEntity multipartReport = (DispositionNotificationMultipartReportEntity) message.getBody(); try { //读取message内容到inputStream InputStream inputStream = multipartReport.getContent(); ByteArrayDataSource datasource = new ByteArrayDataSource(inputStream.readAllBytes(), "multipart/report"); //读取附件 MimeMultipart multipart = new MimeMultipart(datasource); //循环读取附件 for (int i = 0; i < multipart.getCount(); i++) { //读取附件 BodyPart bodyPart = multipart.getBodyPart(i); //判定附件类型 if (bodyPart.isMimeType("text/plain")) { Enumeration<Header> headerEnumeration = bodyPart.getAllHeaders(); while (headerEnumeration.hasMoreElements()) { Header header = headerEnumeration.nextElement(); System.out.println("请求头:"+header.getName() + ": " + header.getValue()); } System.out.println("----------附件内容1-------------"); System.out.println(bodyPart.getContent()); System.out.println("-----------------------"); } else if (bodyPart.isMimeType("application/octet-stream")) { log.info("application/octet-stream"); System.out.println(bodyPart.getContent().getClass()); //processBinaryData(bodyPart.getInputStream()); } else if (bodyPart.isMimeType("message/disposition-notification")) { // MDN! log.info("message/disposition-notification"); Enumeration<Header> headerEnumeration = bodyPart.getAllHeaders(); while (headerEnumeration.hasMoreElements()) { Header header = headerEnumeration.nextElement(); System.out.println("请求头:"+header.getName() + ": " + header.getValue()); } if (bodyPart.getContent() instanceof ByteArrayInputStream) { ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream) bodyPart.getContent(); int n = byteArrayInputStream.available(); byte[] bytes = new byte[n]; byteArrayInputStream.read(bytes, 0, n); String s = new String(bytes, StandardCharsets.UTF_8); System.out.println("----------附件内容2-------------"); System.out.println(s); System.out.println("-----------------------------"); } } else { System.out.println(bodyPart.getContent().getClass()); log.warn("default " + bodyPart.getContentType()); } } } catch (IOException | MessagingException e) { e.printStackTrace(); } } } }
各位童鞋们,到把参考项目下载下来对照着看看就能理解,还原私信交流