使用 Tomcat 的 Spring DataSource JNDI 示例

欢迎来到 Spring DataSource JNDI Tomcat 示例教程. 早些时候我们看到如何使用 Spring JDBC实现数据库操作集成。

春季数据源

我们知道 DataSource with JNDI是实现连接聚合并获得容器实现的好处的首选方法。今天,我们将看看如何配置一个 Spring Web 应用程序以使用 Tomcat 提供的 JNDI 连接。 作为我的例子,我将使用 MySQL 数据库服务器并创建一个简单的表,其中有一些行。

数据库设置

 1CREATE TABLE `Employee` (
 2  `id` int(11) unsigned NOT NULL,
 3  `name` varchar(20) DEFAULT NULL,
 4  `role` varchar(20) DEFAULT NULL,
 5  PRIMARY KEY (`id`)
 6) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 7
 8INSERT INTO `Employee` (`id`, `name`, `role`)
 9VALUES
10    (1, 'Pankaj', 'CEO'),
11    (2, 'David', 'Manager');
12commit;

春季数据源 MVC 项目

Create a Spring MVC Project in the Spring Tool Suite so that our spring application skeleton code is ready. Once we will be done with our implementation, our project structure will look like below image. Spring DataSource, Spring JNDI, Spring Tomcat Example

春季JDBC和杰克逊依赖

我们将不得不添加 Spring JDBC、Jackson 和 MySQL 数据库驱动程序作为 pom.xml 文件中的依赖。

  1<?xml version="1.0" encoding="UTF-8"?>
  2<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  3    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
  4    <modelVersion>4.0.0</modelVersion>
  5    <groupId>com.journaldev.spring</groupId>
  6    <artifactId>SpringDataSource</artifactId>
  7    <name>SpringDataSource</name>
  8    <packaging>war</packaging>
  9    <version>1.0.0-BUILD-SNAPSHOT</version>
 10    <properties>
 11    	<java-version>1.6</java-version>
 12    	<org.springframework-version>4.0.2.RELEASE</org.springframework-version>
 13    	<org.aspectj-version>1.7.4</org.aspectj-version>
 14    	<org.slf4j-version>1.7.5</org.slf4j-version>
 15    	<jackson.databind-version>2.2.3</jackson.databind-version>
 16    </properties>
 17    <dependencies>
 18    	<!-- Spring JDBC Support -->
 19    	<dependency>
 20    		<groupId>org.springframework</groupId>
 21    		<artifactId>spring-jdbc</artifactId>
 22    		<version>${org.springframework-version}</version>
 23    	</dependency>
 24    	
 25    	<!-- MySQL Driver -->
 26    	<dependency>
 27    		<groupId>mysql</groupId>
 28    		<artifactId>mysql-connector-java</artifactId>
 29    		<version>5.0.5</version>
 30    	</dependency>
 31    	<!-- Jackson -->
 32    	<dependency>
 33    		<groupId>com.fasterxml.jackson.core</groupId>
 34    		<artifactId>jackson-databind</artifactId>
 35    		<version>${jackson.databind-version}</version>
 36    	</dependency>
 37    	<!-- Spring -->
 38    	<dependency>
 39    		<groupId>org.springframework</groupId>
 40    		<artifactId>spring-context</artifactId>
 41    		<version>${org.springframework-version}</version>
 42    		<exclusions>
 43    			<!-- Exclude Commons Logging in favor of SLF4j -->
 44    			<exclusion>
 45    				<groupId>commons-logging</groupId>
 46    				<artifactId>commons-logging</artifactId>
 47    			 </exclusion>
 48    		</exclusions>
 49    	</dependency>
 50    	<dependency>
 51    		<groupId>org.springframework</groupId>
 52    		<artifactId>spring-webmvc</artifactId>
 53    		<version>${org.springframework-version}</version>
 54    	</dependency>
 55    			
 56    	<!-- AspectJ -->
 57    	<dependency>
 58    		<groupId>org.aspectj</groupId>
 59    		<artifactId>aspectjrt</artifactId>
 60    		<version>${org.aspectj-version}</version>
 61    	</dependency>	
 62    	
 63    	<!-- Logging -->
 64    	<dependency>
 65    		<groupId>org.slf4j</groupId>
 66    		<artifactId>slf4j-api</artifactId>
 67    		<version>${org.slf4j-version}</version>
 68    	</dependency>
 69    	<dependency>
 70    		<groupId>org.slf4j</groupId>
 71    		<artifactId>jcl-over-slf4j</artifactId>
 72    		<version>${org.slf4j-version}</version>
 73    		<scope>runtime</scope>
 74    	</dependency>
 75    	<dependency>
 76    		<groupId>org.slf4j</groupId>
 77    		<artifactId>slf4j-log4j12</artifactId>
 78    		<version>${org.slf4j-version}</version>
 79    		<scope>runtime</scope>
 80    	</dependency>
 81    	<dependency>
 82    		<groupId>log4j</groupId>
 83    		<artifactId>log4j</artifactId>
 84    		<version>1.2.15</version>
 85    		<exclusions>
 86    			<exclusion>
 87    				<groupId>javax.mail</groupId>
 88    				<artifactId>mail</artifactId>
 89    			</exclusion>
 90    			<exclusion>
 91    				<groupId>javax.jms</groupId>
 92    				<artifactId>jms</artifactId>
 93    			</exclusion>
 94    			<exclusion>
 95    				<groupId>com.sun.jdmk</groupId>
 96    				<artifactId>jmxtools</artifactId>
 97    			</exclusion>
 98    			<exclusion>
 99    				<groupId>com.sun.jmx</groupId>
100    				<artifactId>jmxri</artifactId>
101    			</exclusion>
102    		</exclusions>
103    		<scope>runtime</scope>
104    	</dependency>
105
106    	<!-- @Inject -->
107    	<dependency>
108    		<groupId>javax.inject</groupId>
109    		<artifactId>javax.inject</artifactId>
110    		<version>1</version>
111    	</dependency>
112    			
113    	<!-- Servlet -->
114    	<dependency>
115    		<groupId>javax.servlet</groupId>
116    		<artifactId>servlet-api</artifactId>
117    		<version>2.5</version>
118    		<scope>provided</scope>
119    	</dependency>
120    	<dependency>
121    		<groupId>javax.servlet.jsp</groupId>
122    		<artifactId>jsp-api</artifactId>
123    		<version>2.1</version>
124    		<scope>provided</scope>
125    	</dependency>
126    	<dependency>
127    		<groupId>javax.servlet</groupId>
128    		<artifactId>jstl</artifactId>
129    		<version>1.2</version>
130    	</dependency>
131    
132    	<!-- Test -->
133    	<dependency>
134    		<groupId>junit</groupId>
135    		<artifactId>junit</artifactId>
136    		<version>4.7</version>
137    		<scope>test</scope>
138    	</dependency>        
139    </dependencies>
140    <build>
141        <plugins>
142            <plugin>
143                <artifactId>maven-eclipse-plugin</artifactId>
144                <version>2.9</version>
145                <configuration>
146                    <additionalProjectnatures>
147                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
148                    </additionalProjectnatures>
149                    <additionalBuildcommands>
150                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
151                    </additionalBuildcommands>
152                    <downloadSources>true</downloadSources>
153                    <downloadJavadocs>true</downloadJavadocs>
154                </configuration>
155            </plugin>
156            <plugin>
157                <groupId>org.apache.maven.plugins</groupId>
158                <artifactId>maven-compiler-plugin</artifactId>
159                <version>2.5.1</version>
160                <configuration>
161                    <source>1.6</source>
162                    <target>1.6</target>
163                    <compilerArgument>-Xlint:all</compilerArgument>
164                    <showWarnings>true</showWarnings>
165                    <showDeprecation>true</showDeprecation>
166                </configuration>
167            </plugin>
168            <plugin>
169                <groupId>org.codehaus.mojo</groupId>
170                <artifactId>exec-maven-plugin</artifactId>
171                <version>1.2.1</version>
172                <configuration>
173                    <mainClass>org.test.int1.Main</mainClass>
174                </configuration>
175            </plugin>
176        </plugins>
177    </build>
178</project>

如果你不熟悉春季休息,请阅读( / 社区 / 教程 / 春季休息 - 例子 - 教程 - 春季休息 - 网络服务)。

类型模型

我们的员工表模型为员工表,如下所示。

 1package com.journaldev.spring.jdbc.model;
 2
 3import java.io.Serializable;
 4
 5public class Employee implements Serializable{
 6
 7    private static final long serialVersionUID = -7788619177798333712L;
 8    
 9    private int id;
10    private String name;
11    private String role;
12    
13    public int getId() {
14    	return id;
15    }
16    public void setId(int id) {
17    	this.id = id;
18    }
19    public String getName() {
20    	return name;
21    }
22    public void setName(String name) {
23    	this.name = name;
24    }
25    
26    public String getRole() {
27    	return role;
28    }
29    public void setRole(String role) {
30    	this.role = role;
31    }
32    
33    
34}

春季控制班级

我们的简单的控制器类型看起来像下面。

 1package com.journaldev.spring.jdbc.controller;
 2
 3import java.util.ArrayList;
 4import java.util.List;
 5import java.util.Map;
 6
 7import javax.sql.DataSource;
 8
 9import org.slf4j.Logger;
10import org.slf4j.LoggerFactory;
11import org.springframework.beans.factory.annotation.Autowired;
12import org.springframework.beans.factory.annotation.Qualifier;
13import org.springframework.jdbc.core.JdbcTemplate;
14import org.springframework.stereotype.Controller;
15import org.springframework.web.bind.annotation.RequestMapping;
16import org.springframework.web.bind.annotation.RequestMethod;
17import org.springframework.web.bind.annotation.ResponseBody;
18
19import com.journaldev.spring.jdbc.model.Employee;
20
21/**
22 * Handles requests for the Employee JDBC Service.
23 */
24@Controller
25public class EmployeeController {
26    
27    private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class);
28    
29    @Autowired
30    @Qualifier("dbDataSource")
31    private DataSource dataSource;
32
33    public void setDataSource(DataSource dataSource) {
34    	this.dataSource = dataSource;
35    }
36
37    @RequestMapping(value = "/rest/emps", method = RequestMethod.GET)
38    public @ResponseBody List<Employee> getAllEmployees() {
39    	logger.info("Start getAllEmployees.");
40    	List<Employee> empList = new ArrayList<Employee>();
41    	//JDBC Code - Start
42    	String query = "select id, name, role from Employee";
43    	JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
44
45    	List<Map<String,Object>> empRows = jdbcTemplate.queryForList(query);
46    	
47    	for(Map<String,Object> empRow : empRows){
48    		Employee emp = new Employee();
49    		emp.setId(Integer.parseInt(String.valueOf(empRow.get("id"))));
50    		emp.setName(String.valueOf(empRow.get("name")));
51    		emp.setRole(String.valueOf(empRow.get("role")));
52    		empList.add(emp);
53    	}
54    	
55    	return empList;
56    }
57
58}

关于控制器类的重要点是:

  • DataSource 将由 Spring Bean 配置命名为 dbDataSource *我们正在使用 JdbcTemplate 来避免资源泄露等常见错误,并删除 JDBC 锅炉板代码
  • 获取员工列表的 URI 将是 https://{host}:{port}/SpringDataSource/rest/emps
  • 我们正在使用 @ResponseBody 来发送员工对象列表, Spring 将负责将其转换为 JSON

Spring Bean 配置

有两种方式,我们可以JNDI搜索并将其连接到控制器数据源,我的春豆配置文件包含两者,但其中一个被评论。

  1. 使用 jee namespace 标签来执行 JNDI 搜索并将其配置为 Spring Bean. 在这种情况下,我们还需要包括 jee namespace 和 schema 定义.
  2. 通过传输 JNDI 语境名称来创建一个类型的 bean org.springframework.jndi.JndiObjectFactoryBean

我的春豆配置文件看起来像下面。

 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans:beans xmlns="https://www.springframework.org/schema/mvc"
 3    xmlns:jee="https://www.springframework.org/schema/jee"
 4    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:beans="https://www.springframework.org/schema/beans"
 5    xmlns:context="https://www.springframework.org/schema/context"
 6    xsi:schemaLocation="https://www.springframework.org/schema/jee https://www.springframework.org/schema/jee/spring-jee.xsd
 7    	https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
 8    	https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
 9    	https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
10
11    <!-- DispatcherServlet Context: defines this servlet's request-processing 
12    	infrastructure -->
13
14    <!-- Enables the Spring MVC @Controller programming model -->
15    <annotation-driven />
16
17    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
18    	up static resources in the ${webappRoot}/resources directory -->
19    <resources mapping="/resources/**" location="/resources/" />
20
21    <!-- Resolves views selected for rendering by @Controllers to .jsp resources 
22    	in the /WEB-INF/views directory -->
23    <beans:bean
24    	class="org.springframework.web.servlet.view.InternalResourceViewResolver">
25    	<beans:property name="prefix" value="/WEB-INF/views/" />
26    	<beans:property name="suffix" value=".jsp" />
27    </beans:bean>
28
29    <!-- Configure to plugin JSON as request and response in method handler -->
30    <beans:bean
31    	class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
32    	<beans:property name="messageConverters">
33    		<beans:list>
34    			<beans:ref bean="jsonMessageConverter" />
35    		</beans:list>
36    	</beans:property>
37    </beans:bean>
38
39    <!-- Configure bean to convert JSON to POJO and vice versa -->
40    <beans:bean id="jsonMessageConverter"
41    	class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
42    </beans:bean>
43    
44    <!-- Create DataSource Bean -->
45     
46    <beans:bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
47    	<beans:property name="jndiName" value="java:comp/env/jdbc/MyLocalDB"/>
48    </beans:bean>
49     
50     <!-- using JEE namespace for lookup -->
51     <!-- 
52     <jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/MyLocalDB"
53    		expected-type="javax.sql.DataSource" />
54      -->
55      
56    <context:component-scan base-package="com.journaldev.spring.jdbc.controller" />
57
58</beans:beans>

Tomcat 数据源 JNDI 配置

现在我们已经完成了我们的项目,最后的部分是在Tomcat容器中进行JNDI配置,以创建JNDI资源。

 1<Resource name="jdbc/TestDB" 
 2      global="jdbc/TestDB" 
 3      auth="Container" 
 4      type="javax.sql.DataSource" 
 5      driverClassName="com.mysql.jdbc.Driver" 
 6      url="jdbc:mysql://localhost:3306/TestDB" 
 7      username="pankaj" 
 8      password="pankaj123" 
 9
10      maxActive="100" 
11      maxIdle="20" 
12      minIdle="5" 
13      maxWait="10000"/>

在 server.xml 文件的 GlobalNamingResources 部分中添加上述配置。

1<ResourceLink name="jdbc/MyLocalDB"
2                	global="jdbc/TestDB"
3                    auth="Container"
4                    type="javax.sql.DataSource" />

我们还需要创建资源链接以在我们的应用程序中使用JNDI配置,最好是将其添加到服务器context.xml文件中。请注意,ResourceLink名称应该与我们在我们的应用程序中使用的JNDI背景名称匹配。

运行 Spring DataSource JNDI 样本项目

Our project and server configuration is done and we are ready to test it. Export the project as WAR file and place it in the tomcat deployment directory. The JSON response for the Rest call is shown in the below image. Spring JNDI Example, Spring DataSource That's all for the Spring integration with servlet container JNDI context, download the sample project from the below link and play around with it to learn more.

下载春季数据源JNDI项目

Published At
Categories with 技术
Tagged with
comments powered by Disqus