Mule ESB Http項目轉換爲Tomcat項目(7) 與Spring的結合

       因爲Mule ESB提供的容器自身限制,使它不容易集成第三方庫。爲了解決這個問題,Mule提供了ESB項目與Spring框架的集成。可是這個集成在轉換爲Tomcat項目時會遇到一些問題,下面我會一一加以敘述。java

       ESB項目與spring的集成參考了Mule ESB的Spring集成文檔,地址爲mysql

https://docs.mulesoft.com/mule-user-guide/v/3.8/using-spring-beans-as-flow-componentsspring

       在前面的例子中請求的json報文是固定的,例如{"name":"張三","id":"197"},這樣僅能處理單個用戶,當咱們想處理多個用戶,每一個用戶有多個屬性信息時就不是很方便。咱們想僅僅提供一批須要處理的用戶Id的json報文,例如sql

     

{
	"students":
	[	
		[
			{
				"id":"197"
			},
			{
				"id":"198"
			},
			{
				"id":"199"
			}
		]
	]	
}

 ESB項目解析這樣的json報文,根據id從數據庫裏讀取這些學生的詳細信息,再經過Data Weaver的轉換爲xml報文,輸出如下的xml響應報文:數據庫

<?xml version="1.0" encoding="UTF-8" ?>
<Students>
	<Student>
		<name>張三</name>
		<id>197</id>
		<class>1年1班<class>
	</Student>
	<Student>
		<name>李四</name>
		<id>198</id>
		<class>1年2班</class>
	</Student>
	<Student>
		<name>趙五</name>
		<id>199</id>
		<class>1年3班</class>
	</Student>
</Students>

 根據id從數據庫裏讀取數據咱們可使用Mule ESB提供的jdbc connector,直接鏈接數據庫執行sql查詢,因爲咱們這裏討論spring集成,咱們使用spring jdbc template進行訪問。express

 ESB訪問的數據庫咱們使用MySql 5.5,新建一個test數據庫,編碼集使用utf-8,再在這個數據庫下新建一個students表,建表sql爲json

CREATE TABLE `students` (
  `ID` int(10) NOT NULL,
  `NAME` varchar(255) NOT NULL,
  `CLASS` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

初始化表數據的sql爲app

INSERT INTO `students` VALUES ('197', '張三', '1年1班');
INSERT INTO `students` VALUES ('198', '李四', '1年2班');
INSERT INTO `students` VALUES ('199', '趙五', '1年3班');
INSERT INTO `students` VALUES ('200', '王六', '1年4班');
INSERT INTO `students` VALUES ('201', '孫七', '2年1班');

這樣就創建了ESB項目須要訪問的數據庫。框架

第二步須要在ESB項目中引入Spring Jdbc訪問,咱們首先恢復ESB項目的Maven支持,而後在pom文件中引入spring的庫包(Mule ESB EE 3.8.0 M1版本自帶Spring Framework版本爲 4.1.6,若是用戶想使用不一樣版本的Spring Framework,能夠自行在pom文件中配置,這裏咱們使用最新的4.3.0 RELEASE版本)ide

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.0.RELEASE</version>
</dependency>

再定義Student類,對應studens表的單行記錄

package com.mule.spring.entity;

public class Student 
{
		private Integer id;
		private String name;
		private String className;
............

定義StudentService接口,定義根據Id列表從studens表讀取student的Service層

package com.mule.spring.service;
import java.util.List;
import com.mule.spring.entity.Student;

public interface StudentService 
{
		List<Student> getStudentsByIds(List<String> ids);
}

再定義StudentDao接口,定義根據Ids列表從students表讀取student的Dao層,它的實現類使用spring jdbc template執行具體的查詢命令,而且使用了我自定義的Mapper轉換查詢結果爲Student類對象。

package com.mule.spring.service.impl;

@Service("studentService")
public class StudentServiceImpl implements StudentService {

	@Override
	public List<Student> getStudentsByIds(List<String> ids) {
		// TODO Auto-generated method stub
		return null;
	}
}


package com.mule.spring.dao;

public interface StudentDao 
{
	List<Student> getStudentsByIds(List<String> ids);
}


package com.mule.spring.dao.impl;

@Component("studentDao")
public class StudentDaoImpl implements StudentDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	@Override
	public List<Student> getStudentsByIds(List<String> ids) 
	{
		String idListStr = Joiner.on(',').join(ids);
		String sql = "select * from students where id in (" + idListStr + ")";		
		List<Student> studentList =jdbcTemplate.query(
				sql, new StudentMapper());	
		
		return studentList;
	}
............

這裏咱們使用guava庫用於從id列表得到id字符串,咱們使用的guava版本是19.0

添加完訪問Students表所需的Service和Dao類後,咱們須要在流程中引入Service接口。

打開ESB項目流程圖,咱們在Http Listener節點和DataWeaver節點間拖入一個Java Transformer,自定義一個Customer類,繼承自AbstractJsonTransformer,爲了引入AbstractJsonTransformer接口,咱們須要修改pom文件,添加mule-module-json jar包

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>
<dependency>
    <groupId>org.mule.modules</groupId>
    <artifactId>mule-module-json</artifactId>
    <version>${mule.version}</version>
    <scope>provided</scope>
</dependency>

修改後的流程圖和Data Weaver映射關係圖以下所示

咱們在自定義的Transformer中引入Service

public class CustomJsonTransformer extends AbstractJsonTransformer {

	@Autowired
    protected StudentService studentService;
	
	@Override
	public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
		
		String transformJsonStr = null;
		
		 try {
	            String jsonMessage = message.getPayloadAsString();	            
	            //添加信息
	            JSONObject jsonMap = updateStudentInfos(jsonMessage);
	            transformJsonStr = jsonMap.toJSONString();
	        } 
    .............


    private JSONObject updateStudentInfos(String originalJsonStr)
	{
			JSONObject studentsJsonObj = null;
			try
			{
				studentsJsonObj = JSONObject.parseObject(originalJsonStr);
				JSONArray studentMapArray =
							studentsJsonObj.getJSONArray("students");
				
				//從請求json報文中讀取student的id列表
				List<String> idList = new ArrayList<String>();
		    	int length = studentMapArray.size();		    	
		    	for(int i=0;i<length;i++)
		    	{
		    		JSONObject studentMap = studentMapArray.getJSONObject(i);
		    		String id = studentMap.getString("id");
		    		idList.add(id);
		    	}
		    	//根據student的id列表從數據庫中讀取student信息
				List<Student> studentList = 
						studentService.getStudentsByIds(idList);
				
				//將student信息填充到json報文中。
				for(int j=0;j<length;j++)
		    	{
		    		JSONObject studentMap = studentMapArray.getJSONObject(j);
		    		Student student = studentList.get(j);
		    		String name = student.getName();
		    		String className = student.getClassName();
		    		studentMap.put("name", name);
		    		studentMap.put("class", className);
		    	}
				studentsJsonObj.put("students", studentMapArray);				
			}
			catch(Exception ex)
			{
				ex.printStackTrace();
			}	
			return studentsJsonObj;

咱們先導入mysql  connector庫

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>

再在src/main/app下新建一個conf文件夾,在下面新建applicationContext.xml文件

在src/main/resources下新建jdbc.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=admin

applicationContext.xml的內容爲:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">
    
    <context:annotation-config/> 
    <context:property-placeholder
		ignore-unresolvable="true" location="classpath*:/jdbc.properties" />
    
    <context:component-scan base-package="com.mule.spring">		
		<context:include-filter type="regex" 
                       expression="org.springframework.stereotype.Service" />
	</context:component-scan>   
    
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">                
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
</beans>

最後在ESB項目流程文件中使用spring:import標籤導入applicationContext.xml文件

<spring:beans>
       <spring:import resource="classpath:conf/applicationContext.xml"/>
</spring:beans>

到此爲止,ESB項目便與Spring Framework集成在一塊兒了,不過要運行這個ESB項目,須要將mysql connector jar文件拷貝到Mule ESB運行時的lib/opt目錄下,不然在調用ESB接口時會出現No Suitable Driver的異常

最後運行ESB項目,經過Advanced Rest Client調用ESB接口

ESB項目啓動時,mule-module-spring-config jar包中的SpringXmlConfigurationBuilder類會加載流程文件中import的applicationContext.xml文件,加載了Spring Context對象

MuleArtifactContext類對象(繼承自AbstractXmlApplicationContext類),再加載流程文件中自身定義的元素,能夠理解爲MuleArtifactContext容器中包含了MuleContext容器,所以在查找Bean定義時,先從MuleContext容器中查找,再到父容器MuleArtifcatContext容器中查找,然而這兩個Context容器的包容關係僅限於經過Mule ESB運行時環境啓動ESB項目時才能構建,若是ESB項目改爲了Web項目,這一關係將不復存在,接下來咱們將看到這一點。

相關文章
相關標籤/搜索