apache camel xml dsl sample

本章节继续探讨 apache camel xml dsl 的使用,并且完成几个练习题

初始化数据

sample_user 用户表

1
2
3
4
5
6
7
CREATE TABLE `sample_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`user_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`sex` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

用户表 这看起来如下

id user_name user_code sex
- - - -

sample_role 角色表

1
2
3
4
5
6
CREATE TABLE `sample_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`role_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1
2
INSERT INTO sample_role (`id`, `role_name`, `role_desc`) VALUES (1, 'test', 'test角色');
INSERT INTO sample_role (`id`, `role_name`, `role_desc`) VALUES (2, 'test1', 'test1角色');

角色表 这看起来如下

id role_name role_desc
1 test test角色
2 tes1 test1角色

sample_user_role 用户和角色关系表

1
2
3
4
5
6
CREATE TABLE `sample_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(255) NOT NULL,
`user_id` bigint(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

用户和角色关系表 这看起来如下

id role_id user_id
- - -

习题一

开发一个http restful服务,实现用户和角色表的数据插入,初始化数据库默认已经存在角色 test 和 test1 的角色数据.
要求入参:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<xml>
<data>
<user>
<usercode>zhangsan</usercode>
<username>张三</username>
<sex>1</sex>
</user>
<userRoles>
<userRole>
<usercode>zhangsan</usercode>
<rolecode>test</rolecode>
</userRole>
<userRole>
<usercode>zhangsan</usercode>
<rolecode>test1</rolecode>
</userRole>
</userRoles>
</data>
</xml>

要求出参:

1
2
3
4
5
<xml>
<code>1</code>
<msg></msg>
<data></data>
</xml>

分析:
No.1 插入用户表->张三 (sample_user)
No.2 根据角色code查询角色id (sample_role)
No.3 将角色id和插入后的用户id 用户和角色关系表 (sample_user_role)

答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!-- http客户端使用 post body xml 方式 -->
<routes
xmlns="http://camel.apache.org/schema/spring">
<route id="A001" autoStartup="true">
<!-- 使用jetty组件启动一个http服务 9008 /user/insertUser POST -->
<from uri="jetty:http://0.0.0.0:9008/user/insertUser?httpMethodRestrict=POST"/>

<!-- 将客户端传递的xml字符串转换成对象 -->
<convertBodyTo type="java.lang.String"/>
<unmarshal id="unmarshal001">
<jacksonxml/>
</unmarshal>

<!-- 存储临时变量 -->
<setHeader name="userName">
<simple>${body[data][user][username]}</simple>
</setHeader>
<setHeader name="userSex">
<simple>${body[data][user][sex]}</simple>
</setHeader>
<setHeader name="userCode">
<simple>${body[data][user][usercode]}</simple>
</setHeader>

<!-- 设置自增id -->
<setHeader name="CamelSqlRetrieveGeneratedKeys">
<constant>true</constant>
</setHeader>
<setHeader name="CamelSqlGeneratedColumns">
<simple resultType="String[]">id</simple>
</setHeader>

<!-- 插入用户表 -->
<to uri="sql:insert into sample_user(user_name,user_code,sex) values (:#userName,:#userCode,:#userSex)"/>

<!-- 获取自增id -->
<setHeader name="insertUserAfterId">
<simple>${header[CamelSqlGeneratedKeyRows[0][GENERATED_KEY]]}</simple>
</setHeader>

<!-- 保存用户与角色关系表 -->
<split>
<simple>${body[data][userRoles][userRole]}</simple>
<toD uri="sql:insert into sample_user_role(user_id,role_id) VALUES( ${header[insertUserAfterId]}, (select r.id from sample_role r where r.role_name = :#rolecode ))"/>
</split>

<!-- 设置返回值 -->
<setBody>
<simple><![CDATA[<xml><code>1</code><msg></msg><data></data></xml>]]></simple>
</setBody>
<setHeader name="Content-Type">
<constant>application/xml; charset=utf-8</constant>
</setHeader>
</route>
</routes>

okay!

习题二

开发一个http restful服务,实现主从表的查询
(查询某个用户的信息,以及对应的角色信息)
要求入参:

1
2
3
4
5
6
7
<xml>
<data>
<user>
<usercode>zhangsan</usercode>
</user>
</data>
</xml>

要求出参:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<xml>
<code>1</code>
<msg></msg>
<data>
<user>
<usercode>zhangsan</usercode>
<username>张三</username>
<sex>1</sex>
<userRoles>
<userRoles>
<usercode>zhangsan</usercode>
<rolecode>test</rolecode>
</userRoles>
<userRoles>
<usercode>zhangsan</usercode>
<rolecode>test1</rolecode>
</userRoles>
</userRoles>
</user>
</data>
</xml>

分析:

No.1 查询用户和角色信息

No.2 这里的出参在 xml dsl 中无法处理,我们需要编写一个java处理类.

答:
java 处理类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package net.wchar.camel.sample.process;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.Data;
import lombok.ToString;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedCaseInsensitiveMap;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/***
* bean name = example2Process
* @author wchar.net
*/
@Component(value = "example2Process")
public class Example2Process implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
List<LinkedCaseInsensitiveMap<String>> body = (List<LinkedCaseInsensitiveMap<String>>) exchange.getIn().getBody();
Map<String, Object> rootMap = new LinkedHashMap<>();
rootMap.put("code", "1");
rootMap.put("msg", "");
DataNode dataNode = new DataNode();
User user = new User();
List<UserRole> userRoles = new ArrayList<>();

for (LinkedCaseInsensitiveMap<String> itemMap : body) {
user.setUsercode(itemMap.get("user_code"));
user.setUsername(itemMap.get("user_name"));
user.setSex(itemMap.get("sex"));

UserRole userRole = new UserRole();
userRole.setUsercode(itemMap.get("user_code"));
userRole.setRolecode(itemMap.get("role_name"));
userRoles.add(userRole);
}
user.setUserRoles(userRoles);
dataNode.setUser(user);
rootMap.put("data", dataNode);

//设置body并输出
String bodyStr = new XmlMapper().writer().withRootName("xml").writeValueAsString(rootMap);
exchange.getIn().setBody(bodyStr, String.class);
exchange.getIn().setHeader("Content-Type", "application/xml; charset=utf-8");
}

@Data
@ToString
private static class DataNode {
private User user;
}


@Data
@ToString
private static class User {
private String usercode;
private String username;
private String sex;
private List<UserRole> userRoles;
}

@Data
@ToString
private static class UserRole {
private String usercode;
private String rolecode;
}

}

xml dsl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- http客户端使用 post body xml 方式 -->
<routes
xmlns="http://camel.apache.org/schema/spring">
<route id="A001" autoStartup="true">
<!-- 使用jetty组件启动一个http服务 9008 /user/getUser POST -->
<from uri="jetty:http://0.0.0.0:9008/user/getUser?httpMethodRestrict=POST"/>

<!-- 将客户端传递的xml字符串转换成对象 -->
<convertBodyTo type="java.lang.String"/>
<unmarshal id="unmarshal001">
<jacksonxml/>
</unmarshal>

<!-- 存储临时变量 -->
<setHeader name="userCode">
<simple>${body[data][user][usercode]}</simple>
</setHeader>

<!-- 查询用户和角色信息-->
<toD uri="sql:SELECT u.user_code, u.user_name, u.sex, role.role_name, role.role_desc FROM sample_role role,sample_user_role urole,sample_user u WHERE role.id = urole.role_id AND urole.user_id = u.id AND u.id =(SELECT u.id FROM sample_user u WHERE u.user_code = :#userCode )"/>

<!--调用java处理程序-->
<process ref="example2Process" />
</route>
</routes>

okay!

习题三

开发一个http restful服务,根据条件插入不同的角色:
性别为1是角色为test
性别为2时角色是test1
分别插入到用户表和用户角色表中
初始化数据库默认已经存在角色代码为test和test1的角色
要求入参:

1
2
3
4
5
6
7
8
9
<xml>
<data>
<user>
<usercode>wangwu</usercode>
<username>王五</username>
<sex>1</sex>
</user>
</data>
</xml>

要求出参:

1
2
3
4
5
<xml>
<code>1</code>
<msg></msg>
<data></data>
</xml>

分析:

1
2
3
4
5
6
这里要根据sex字段判断是哪个角色 
sex = 1 角色 = test
sex = 2 角色 = test1

No.1 插入用户表
No.2 插入用户角色表

答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<!-- http客户端使用 post body xml 方式 -->
<routes
xmlns="http://camel.apache.org/schema/spring">
<route id="A001" autoStartup="true">

<!-- 使用jetty组件启动一个http服务 9008 /user/insertUserRole POST -->
<from uri="jetty:http://0.0.0.0:9008/user/insertUserRole?httpMethodRestrict=POST"/>

<!-- 将客户端传递的xml字符串转换成对象 -->
<convertBodyTo type="java.lang.String"/>
<unmarshal id="unmarshal001">
<jacksonxml/>
</unmarshal>

<!-- 存储临时变量 -->
<setHeader name="userName">
<simple>${body[data][user][username]}</simple>
</setHeader>
<setHeader name="userSex">
<simple>${body[data][user][sex]}</simple>
</setHeader>
<setHeader name="userCode">
<simple>${body[data][user][usercode]}</simple>
</setHeader>

<!-- 设置自增id -->
<setHeader name="CamelSqlRetrieveGeneratedKeys">
<constant>true</constant>
</setHeader>
<setHeader name="CamelSqlGeneratedColumns">
<simple resultType="String[]">id</simple>
</setHeader>

<!-- 插入用户表 -->
<to uri="sql:insert into sample_user(user_name,user_code,sex) values (:#userName,:#userCode,:#userSex)"/>

<!-- 获取自增id -->
<setHeader name="insertUserAfterId">
<simple>${header[CamelSqlGeneratedKeyRows[0][GENERATED_KEY]]}</simple>
</setHeader>

<!-- 当sex == 1时 是test角色
当sex == 2时 是test1角色-->

<!-- 存储临时变量 -->
<setHeader name="tempRoleCodeForTest">
<constant>test</constant>
</setHeader>
<setHeader name="tempRoleCodeForTest1">
<constant>test1</constant>
</setHeader>

<!-- 判断 sex -->
<choice>
<when>
<simple>${header.userSex} == 1</simple>
<toD uri="sql:insert into sample_user_role(user_id,role_id) VALUES( ${header[insertUserAfterId]},(SELECT r.id FROM sample_role r WHERE r.role_name = :#tempRoleCodeForTest ))" />
</when>
<when>
<simple>${header.userSex} == 2</simple>
<toD uri="sql:insert into sample_user_role(user_id, role_id) VALUES ( ${header[insertUserAfterId]},(SELECT r.id FROM sample_role r WHERE r.role_name = :#tempRoleCodeForTest1 ))" />
</when>
<otherwise>
<!--do nothing-->
</otherwise>
</choice>

<!-- 设置返回值 -->
<setBody>
<simple><![CDATA[<xml><code>1</code><msg></msg><data></data></xml>]]></simple>
</setBody>
<setHeader name="Content-Type">
<constant>application/xml; charset=utf-8</constant>
</setHeader>
</route>
</routes>

okay!

结尾

这里使用了 jackson xml 组件来处理xml

1
2
3
4
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jacksonxml-starter</artifactId>
</dependency>

camel插入数据库后获取自增列配置

1
2
3
4
5
6
7
8
9
10
11
12
<!--开启插入后返回主键-->
<setHeader name="CamelSqlRetrieveGeneratedKeys">
<constant>true</constant>
</setHeader>

<!--表中自动增加的列-->
<setHeader name="CamelSqlGeneratedColumns">
<simple resultType="String[]">id</simple>
</setHeader>

<!-- 获取自增id -->
${header[CamelSqlGeneratedKeyRows[0][GENERATED_KEY]]}

本次就编写到这里了,欢迎访问 wchar.net
o( ̄▽ ̄)ブ