集成服务
依赖包的引入
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>simple-service-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>simple-service-webapp</name>
<properties>
<JDK.version>1.7</JDK.version>
<jersey.version>2.25</jersey.version>
<junit.version>4.12</junit.version>
<slf4j.version>1.7.21</slf4j.version>
<log4j.version>1.2.17</log4j.version>
<spring.version>3.2.17.RELEASE</spring.version>
<jquery.version>3.1.1</jquery.version>
<mysql-connector.version>5.1.38</mysql-connector.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-compiler-plugin.version>2.5.1</maven-compiler-plugin.version>
<maven-war-plugin.version>2.3</maven-war-plugin.version>
<maven-resources-plugin.version>2.6</maven-resources-plugin.version>
<maven-eclipse-plugin.version>2.9</maven-eclipse-plugin.version>
<jetty.version>6.1.5</jetty.version>
<mybatis.version>3.4.1</mybatis.version>
<mybatis-spring.version>1.3.0</mybatis-spring.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
<aspectjweaver.version>1.8.9</aspectjweaver.version>
<aopalliance.version>1.0</aopalliance.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${JDK.version}</source>
<target>${JDK.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
</plugin>
<plugin>
<!-- support eclipse's web server -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>${maven-eclipse-plugin.version}</version>
<configuration>
<downloadSources>false</downloadSources>
<wtpversion>2.0</wtpversion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>${jetty.version}</version>
</plugin>
</plugins>
</build>
<dependencies>
<!-- jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- media type -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- jersey-spring -->
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- unit test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- Jersey test containers -->
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-inmemory</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jdk-http</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-simple</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- web jars -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>${jquery.version}</version>
</dependency>
<!-- log -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<!--<scope>runtime</scope> -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- aop,事务控制 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>${aopalliance.version}</version>
</dependency>
<!-- db -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
</dependency>
</dependencies>
<pluginRepositories>
<pluginRepository>
<id>snapshots.codehaus.org</id>
<name>Codehaus.org Snapshots Maven Repository</name>
<url>http://nexus.codehaus.org/snapshots</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>release.maven.java.net</id>
<name>java.net Maven Release Repository</name>
<url>https://maven.java.net/content/groups/public</url>
<layout>default</layout>
</repository>
</repositories>
</project>
该工程集成spring和mybatis,使用mysql数据库。
集成spring
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 对包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 -->
<context:component-scan base-package="com.example" />
<!-- aop配置 -->
<aop:aspectj-autoproxy />
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="initialSize" value="${initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mapper/configuration.xml"></property>
</bean>
<!-- 配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务注解驱动,标注@Transactional的类和方法将具有事务性 -->
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>simple-service-webapp</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
数据库配置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.183.129:3306/mysql?useUnicode=true&characterEncoding=UTF-8
username=root
password=duckking
initialSize=0
maxActive=20
maxIdle=20
minIdle=1
maxWait=60000
创建数据库连接
在spring的配置中创建数据库连接,用的是dhcp的代码来创建的:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="initialSize" value="${initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"></property>
</bean>
集成mybatis
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mapper/configuration.xml"></property>
</bean>
用SqlSessionFactoryBean初始化数据,配置文件是configuration.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.4//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias alias="Book" type="com.example.bo.Book" />
<typeAlias alias="Books" type="com.example.bo.Books" />
</typeAliases>
<mappers>
<mapper resource="mapper/books.xml" />
</mappers>
</configuration>
mybatis使用数据库的mapper如下:books.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="default namespace">
</mapper>
现在我们建立起了一个由jersey提供api,后端集成了spring和mybatis的框架,还有一引动其它的小功能,如日志、测试等,但里面内容还是空的,现在我们向时面加内容。
定义实体类
@XmlRootElement
public class Book {
private Long bookId;
private String bookName;
private String publisher;
@XmlAttribute
public Long getBookId() {
return bookId;
}
public void setBookId(Long bookId) {
this.bookId = bookId;
}
@XmlAttribute
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
@XmlAttribute
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
}
@XmlRootElement(name = "books")
public class Books implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1398511916695349225L;
private List<Book> bookList;
@XmlElement(name = "book")
@XmlElementWrapper
public List<Book> getBookList() {
return bookList;
}
public void setBookList(List<Book> bookList) {
this.bookList = bookList;
}
}
定义资源类
@Path("books")public class BookResource {
private static final Logger logger = LoggerFactory.getLogger(BookResource.class);
@Autowired
private BookService bookService;
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Books getAlBooks() {
final Books books = bookService.getAllBooks();
return books;
}
@Path("{bookId:[0-9]*}")
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Book getBookByPath(@PathParam("bookId") final Long bookId) {
logger.info("bookId=" + bookId);
final Book book = bookService.getBook(bookId);
return book;
}
@Path("/book")
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Book getBookByQuery(@QueryParam("id") final Long bookId) {
final Book book = bookService.getBook(bookId);
return book;
}
}
上述三个方法访问的方式分别为:
http://localhost:8080/simple-service-webapp/webapi/books
http://localhost:8080/simple-service-webapp/webapi/books/1
http://localhost:8080/simple-service-webapp/webapi/books/book?id=1
中间service层没有什么好说的,看下Dao层:
@Repository("bookDao")
public class BookDao extends SqlSessionDaoSupport {
@Autowired
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
public Books getAllBooks() {
List<Book> bookList = this.getSqlSession().selectList("getAllBooks");
Books books = new Books();
books.setBookList(bookList);
return books;
}
public Book findById(final String bookId) {
logger.info("bookId=" + bookId);
return (Book) this.getSqlSession().selectOne("findById", bookId);
}
}
在执行过程中可以看到后台日志:
[DEBUG] 2016-12-12 22:39:37,113 method:org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:99)
Creating a new SqlSession
[DEBUG] 2016-12-12 22:39:37,113 method:org.mybatis.spring.SqlSessionUtils.registerSessionHolder(SqlSessionUtils.java:150)
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a753a0] was not registered for synchronization because synchronization is not active
[DEBUG] 2016-12-12 22:39:37,114 method:org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:110)
Fetching JDBC Connection from DataSource
[DEBUG] 2016-12-12 22:39:37,118 method:org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:89)
JDBC Connection [jdbc:mysql://192.168.183.129:3306/mysql?useUnicode=true&characterEncoding=UTF-8, UserName=root@192.168.183.1, MySQL Connector Java] will not be managed
by Spring
[DEBUG] 2016-12-12 22:39:37,119 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:145)
==> Preparing: SELECT bookid,bookname,publisher FROM book where bookid=?
[DEBUG] 2016-12-12 22:39:37,121 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:145)
==> Parameters: 1(String)
[DEBUG] 2016-12-12 22:39:37,125 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:145)
<== Total: 1
[DEBUG] 2016-12-12 22:39:37,125 method:org.mybatis.spring.SqlSessionUtils.closeSqlSession(SqlSessionUtils.java:193)
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a753a0]
[DEBUG] 2016-12-12 22:39:37,126 method:org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:327)
Returning JDBC Connection to DataSource
发布服务
定义一个application类,由application类发布接口:
public class AirApplication2 extends ResourceConfig {
public AirApplication2() {
packages("com.example.resource");
}
}
将Application启动,在web.xml中配置。
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.AirApplication2</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
一个后台服务就发布完成了,可以通过浏览器直接访问url的方式访问api了。
前台框架jQuery
我们前端使用augularJS来实现,这里不讲解jQuery通过Ajax来访问后台的具体内容。
测试框架
通过firefox的resteasy或rested插件来进行测试。