Spring mvc + Hibernate + Jpa + druid 全注解配置实例

搭建一个模板,以备忘。

简介

本文搭建的是基于spring mvc的全注解的环境,集成jpa/hibernate/druid/fastjson,日志采用的是logback。
主要配置文件包括

//maven库
pom.xml
web.xml
//mvc相关配置
spring-mvc.xml
//spring容器配置
spring-root.xml
//日志配置
logback.xml
//数据库和其他配置文件
*.properties

配置篇

pom.xml

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk-version>1.6</jdk-version>
<junit-version>4.11</junit-version>
<spring-version>3.2.4.RELEASE</spring-version>
</properties>

<dependencies>
<!-- spring begin-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</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-context-support</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
<!-- spring end -->


<!-- servlet begin -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<!-- servlet end -->


<!-- junit begin -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<!-- junit end -->


<!-- hibernate begin -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>4.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.0.Final</version>
</dependency>
<!-- hibernate end -->


<!--logger begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>

<!-- logger end -->


<!-- database begin -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<!-- database end -->


<!-- apache commons begin -->
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>

<!-- apache commons end -->

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.16</version>
</dependency>

<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.2</version>
</dependency>

<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>

<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.6</version>
</dependency>

<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.7</version>
</dependency>
</dependencies>

web.xml

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
77
78
79
80
81
82
83
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="true" version="3.0">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath*:/logback.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-root.xml</param-value>
</context-param>

<!-- 設定Spring Context的默认Profile -->
<!--<context-param>-->
<!--<param-name>spring.profiles.default</param-name>-->
<!--<param-value>development</param-value>-->
<!--</context-param>-->

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 配置spring mvc -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!-- 字符集 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- druid监控 -->
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- druid监控 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>

spring-mvc.xml

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
77
78
79
80
81
82
83
84
85
86
<?xml version="1.0" encoding="UTF-8"?>
<!-- Bean头部 -->
<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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">


<!--对包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 需要更改-->
<context:component-scan base-package="com.zzcm.log.action" />

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

<!-- 内容协商管理器 -->
<!--1、首先检查路径扩展名(如my.pdf);2、其次检查Parameter(如my?format=pdf);3、检查Accept Header-->
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<!-- 扩展名至mimeType的映射,即 /user.json => application/json -->
<!--<property name="favorPathExtension" value="false"/>-->
<!--&lt;!&ndash; 用于开启 /userinfo/123?format=json 的支持 &ndash;&gt;-->
<!--<property name="favorParameter" value="false"/>-->
<!--<property name="parameterName" value="format"/>-->
<!--&lt;!&ndash; 是否忽略Accept Header &ndash;&gt;-->
<!--<property name="ignoreAcceptHeader" value="false"/>-->

<property name="mediaTypes"> <!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用 -->
<value>
json=application/json
xml=application/xml
html=text/html
*=*/*
</value>
</property>
</bean>

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters register-defaults="true">
<!--<ref bean="stringHttpMessageConverter" />-->
<!--<ref bean="fastJsonHttpMessageConverter" />-->
<!-- StringHttpMessageConverter编码为UTF-8,防止乱码 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
<property name = "supportedMediaTypes">
<list>
<bean class="org.springframework.http.MediaType">
<constructor-arg index="0" value="text"/>
<constructor-arg index="1" value="plain"/>
<constructor-arg index="2" value="UTF-8"/>
</bean>
<bean class="org.springframework.http.MediaType">
<constructor-arg index="0" value="*"/>
<constructor-arg index="1" value="*"/>
<constructor-arg index="2" value="UTF-8"/>
</bean>
</list>
</property>
</bean>

<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/plain;charset=utf-8</value>
<value>text/html;charset=utf-8</value>
</list>
</property>
<property name="features">
<value type="com.alibaba.fastjson.serializer.SerializerFeature">WriteDateUseDateFormat</value>
<!--这个地方加上这个功能吧,能自己配置一些东西,比如时间的格式化,null输出""等等-->
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>

spring-root.xml及相关文件

spring-root.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"

default-lazy-init="false">


<!-- 加载配置属性文件 ,获取jdbc等相关信息,db中已经有了,本处就省略了 -->
<!--<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">-->
<!--<property name="locations">-->
<!--<list>-->
<!--<value>classpath*:db.properties</value>-->
<!--</list>-->
<!--</property>-->
<!--</bean>-->

<import resource="classpath*:spring-db.xml"/>

<!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->
<context:component-scan base-package="com.zzcm.log">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

<!-- JSR303 Validator定义 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

<!-- 支持上传文件 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<property name="maxUploadSize" value="104857600"/>
</bean>


<!-- AOP自动注解功能 -->
<!--<aop:aspectj-autoproxy />-->
</beans>

spring-db.xml

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"

default-lazy-init="false">

<!-- 引入属性文件 -->
<context:property-placeholder location="classpath:db.properties" />

<!-- mysql数据源配置 -->
<bean id="mysqlDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">

<!-- 驱动名称 -->
<property name="DriverClassName" value="${jdbc.driver}" />
<!-- JDBC连接串 -->
<property name="url" value="${jdbc.url}" />
<!-- 数据库用户名称 -->
<property name="username" value="${jdbc.username}" />
<!-- 数据库密码 -->
<property name="password" value="${jdbc.password}" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" />
<!-- 初始化大小 -->
<property name="initialSize" value="5" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<!-- 连接池最小空闲 -->
<property name="minIdle" value="2" />
<!-- 逐出连接的检测时间间隔 -->
<property name="timeBetweenEvictionRunsMillis" value="3000" />
<!-- 最小逐出时间 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- 测试有效用的SQL Query -->
<property name="validationQuery" value="SELECT 'x'" />
<!-- 连接空闲时测试是否有效 -->
<property name="testWhileIdle" value="true" />
<!-- 获取连接时测试是否有效 -->
<property name="testOnBorrow" value="false" />
<!-- 归还连接时是否测试有效 -->
<property name="testOnReturn" value="false" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="wall,stat" />
</bean>

<!-- 整合mysqljpa -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDataSource"></property>
<property name="packagesToScan" value="com.zzcm.log"></property>
<property name="persistenceUnitName" value="mysqldb"></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"></property>
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
<property name="jpaProperties">
<props>
<!--设置外连接抓取树的最大深度 -->
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">18</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<!-- 自动建表类型 validate|create|create-drop|update -->
<!-- <prop key="hibernate.hbm2ddl.auto">validate</prop> -->
<!-- 是否显示SQL -->
<prop key="hibernate.show_sql">true</prop>
<!-- 显示SQL是否格式化 -->
<prop key="hibernate.format_sql">false</prop>
<!-- 关闭二级缓存 -->
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<!-- 关闭实体字段映射校验 -->
<prop key="javax.persistence.validation.mode">none</prop>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
</props>
</property>
</bean>

<!-- Jpa 事务配置 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- Spring Data Jpa配置 -->
<!--
<jpa:repositories base-package="cn.ibeans" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
-->

<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
</beans>

logback.xml

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
<?xml version="1.0"?>
<configuration>
<contextName>LogMng</contextName>
<property name="logname" value="logmng"/>
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<!-- ch.qos.logback.core.ConsoleAppender 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%-5level] %d{HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
</pattern>
</encoder>
</appender>

<!-- ch.qos.logback.core.rolling.RollingFileAppender 文件日志输出 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Encoding>UTF-8</Encoding>
<File>/home/logs/${logname}/${logname}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>/home/logs/${logname}/${logname}-%d{yyyy-MM-dd}.log
</FileNamePattern>
<MaxHistory>30</MaxHistory>
<!--<TimeBasedFileNamingAndTriggeringPolicy-->
<!--class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">-->
<!--<MaxFileSize>5MB</MaxFileSize>-->
<!--</TimeBasedFileNamingAndTriggeringPolicy>-->
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%-5level] %d{HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
</pattern>
</layout>
</appender>

<logger name="com.xxxx.log" level="DEBUG">
<appender-ref ref="console" />
<appender-ref ref="file" />
</logger>

<!-- 日志级别 -->
<root>
<!-- 定义了ERROR和INFO级别的日志,分别在FILE文件和控制台输出 -->
<level value="error" />
<level value="info" />
<appender-ref ref="file" />
<appender-ref ref="console" />
</root>

</configuration>

其他properties

db.properties

1
2
3
4
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://ip:3306/dbname?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf8
jdbc.username=user
jdbc.password=password

实现篇

包括实体的定义,dao,service,controller

Entity

Task.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
@Entity
@Table(name = "t_task")
public class Task {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;

private String name;
@Column(name = "group_name")
private String group;

@JoinColumn(name = "n_from",referencedColumnName = "id")
@ManyToOne
private Node from;
@JoinColumn(name = "n_to",referencedColumnName = "id")
@ManyToOne
private Node to;
@Column(name = "crontime")
private String cronTime;

private Boolean enable;

private Boolean sync;

@Column(name = "dir_from")
private String fromDir;
@Column(name = "filename")
private String fileName;
@Column(name = "dir_to")
private String toDir;

//@Transient
@Enumerated(value = EnumType.ORDINAL)
private Status status = Status.STOP;

//TOADD getter setter

public static enum Status{
STOP(0,"停止"),
RUN(1,"运行"),
PAUSE(2,"暂停");
private int code;
private String desc;
private Status(int code,String desc){
this.code = code;
this.desc = desc;
}

//TOADD getter setter
}
}

TOADD 的自己补全。

dao层

BaseDao.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface BaseDao<T,K extends Serializable> {

public T findById(K id);

public T saveOrUpdate(T bean);

public boolean deleteById(K id);

public boolean delete(T bean);

public T update(T bean);

public List<T> getAll();
}

BaseDaoImpl.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
* Created by Administrator on 2015/12/22.
*/

public abstract class BaseDaoImpl<T,K extends Serializable> implements BaseDao<T,K>{
protected final Logger LOGGER = LoggerFactory.getLogger(getBeanClass());

@PersistenceContext
protected EntityManager em;

protected Class<T> beanClass;

@Override
public T findById(K id) {
try {
return em.find(getBeanClass(),id);
}catch (Exception e){
LOGGER.error("find bean by id["+id+"] failed.",e);
}
return null;
}

@Override
public T saveOrUpdate(T bean) {
try {
em.persist(bean);
return bean ;
} catch (Exception e) {
LOGGER.error("saveOrUpdate bean["+bean+"] failed.",e);
}
return null;
}

@Override
public boolean deleteById(K id) {
try {
T bean = findById(id);
if(null==bean) return false;
em.remove(bean);
return true ;
} catch (Exception e) {
LOGGER.error("delete bean by id["+id+"] failed.",e);
}
return false ;
}

@Override
public boolean delete(T bean) {
try {
em.remove(bean);
return true ;
} catch (Exception e) {
LOGGER.error("delete bean["+bean+"] failed.",e);
}
return false ;
}

@Override
public T update(T bean) {
try {
return em.merge(bean);
} catch (Exception e) {
LOGGER.error("update bean["+bean+"] failed.",e);
}
return null;
}

@Override
public List<T> getAll() {
try {
Query query = em.createQuery("from "+getBeanClass().getSimpleName());
return query.getResultList();
}catch (Exception e){
LOGGER.error("getEnableTasks failed.",e);
}
return null;
}

protected Class<T> getBeanClass(){
if(null == beanClass){
ParameterizedType parameterizedType = (ParameterizedType)this.getClass().getGenericSuperclass();
beanClass = (Class<T>)parameterizedType.getActualTypeArguments()[0];
}
return beanClass;
}
}

TaskDao.java

1
2
3
public interface TaskDao extends BaseDao<Task,Integer>{
public List<Task> getEnableTasks();
}

TaskDaoImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Repository
public class TaskDaoImpl extends BaseDaoImpl<Task,Integer> implements TaskDao{

@Override
public List<Task> getEnableTasks() {
try {
Query query = em.createQuery("from Task where enable = true");
return query.getResultList();
}catch (Exception e){
LOGGER.error("getEnableTasks failed.",e);
}
return null;
}
}

service层

BaseService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface BaseService<T,K extends Serializable> {
public T findById(K id);

public T saveOrUpdate(T bean);

public boolean deleteById(K id);

public boolean delete(T bean);

public T update(T bean);

public List<T> getAll();
}

BaseServiceImpl.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
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;

/**
* Created by Administrator on 2015/12/24.
*/

public abstract class BaseServiceImpl<T,K extends Serializable> implements BaseService<T,K>{

@Override
public T findById(K id) {
return getBaseDao().findById(id);
}

@Override
@Transactional
public T saveOrUpdate(T bean) {
return getBaseDao().saveOrUpdate(bean);
}

@Override
@Transactional
public boolean deleteById(K id) {
return getBaseDao().deleteById(id);
}

@Override
@Transactional
public boolean delete(T bean) {
return getBaseDao().delete(bean);
}

@Override
@Transactional
public T update(T bean) {
return getBaseDao().update(bean);
}

@Override
public List<T> getAll() {
return getBaseDao().getAll();
}

protected abstract BaseDao<T,K> getBaseDao();
}

TaskService.java

1
2
3
public interface TaskService extends BaseService<Task,Integer>{

}

TaskServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
* Created by Administrator on 2015/12/23.
*/

@Component
public class TaskServiceImpl extends BaseServiceImpl<Task,Integer> implements TaskService{
private static final Logger LOG = LoggerFactory.getLogger(TaskServiceImpl.class);

@Autowired
private TaskDao dao;

@Override
protected BaseDao<Task, Integer> getBaseDao() {
return dao;
}
}

controller

TaskAct.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
75
76
77
78
79
80
81
82
83
84
85
86
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
* Created by Administrator on 2015/12/23.
*/
@Controller
@RequestMapping(value = "/task")
public class TaskAct {

private static Logger log = LoggerFactory.getLogger(TaskAct.class);

@Autowired
private TaskService taskService;
@Autowired
private NodeService nodeService;

@RequestMapping(value="/{id}")
public @ResponseBody Task json(@PathVariable Integer id,ModelMap model,HttpServletRequest request,
HttpServletResponse response){
log.info("id2:"+id);
//SFTPUtil.download("192.168.0.180", "root", "zzcm2014", "/opt", "cid.jar", "D:/test/aaaa.jar");
//ResponseUtils.renderJson(response, "true");
return taskService.findById(1);
}

@RequestMapping(value="/")
public String list(Model model,RedirectAttributes attr){
List<Task> tasks = taskService.getAll();
model.addAttribute("tasks",tasks);
//attr.addFlashAttribute(user);
//attr.addFlashAttribute("user",user);
return "/task/list";
}

@RequestMapping(value="/add",method = RequestMethod.GET)
public String add(Model model){
List<Node> nodes =nodeService.getAllNodes();
model.addAttribute("nodes",nodes);
return "/task/add";
}

@RequestMapping(value="/add",method = RequestMethod.POST)
public String add(@ModelAttribute Task task, Model model){
Node node = nodeService.findById(task.getFrom().getId());
task.setFrom(node);
taskService.insertTask(task);
return "redirect:/task/";
}

@RequestMapping(value="/update/{id:\\d+}",method = RequestMethod.GET)
public String update(@PathVariable Integer id,Model model){
List<Node> nodes =nodeService.getAllNodes();
Task task = taskService.findById(id);
if(task.getStatus() != Task.Status.STOP){
return "redirect:/task/";
}
model.addAttribute("task",task);
model.addAttribute("nodes",nodes);
return "/task/add";
}

@RequestMapping(value="/update",method = RequestMethod.POST)
public String update(@ModelAttribute Task task, Model model){
//Node node = nodeService.findById(task.getFrom().getId());
//task.setFrom(node);
taskService.saveOrUpdate(task);
return "redirect:/task/";
}

@RequestMapping(value="/delete/{id}")
public String delete(@PathVariable Integer id, Model model){
taskService.deleteTask(id);
return "redirect:/task/";
}
}

其中第一个方法(json)是JSON返回。

jsp

jsp文件放置位置由spring-mvc.xml和controller返回值共同决定。

list.jsp

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
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>任务列表</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<%--<script src="/js/jquery-1.11.3.js" style="text/javascript"/>--%>
</head>
<body>
<a href="/task/add">添加任务</a>
<table border="1">
<thead>
<td>ID</td>
<td>名称</td>
<td>组名</td>
<td>源地址</td>
<td>时间</td>
<td>状态</td>
<td>是否启用</td>
<td>是否异步</td>
<td>操作</td>
</thead>
<%--<c:if test="${not empty tasks}">--%>
<%--sssss--%>
<%--</c:if>--%>
<c:forEach items="${tasks}" var="task" varStatus="vs">
<tr>
<td align = "center">${task.id}</td>
<td align = "center">${task.name}</td>
<td align = "center">${task.group}</td>
<td align = "center">${task.from.name}</td>
<td align = "center">${task.cronTime}</td>
<td align = "center">${task.status.desc}${task.status.code}</td>
<td align = "center">${task.enable}</td>
<td align = "center">${task.sync}</td>
<td align = "center">
<c:if test="${(empty task.status or task.status.code==0) and task.enable}">
<a href="/task/disable/${task.id}">禁用</a>
<a href="/task/start/${task.id}">启动</a>
</c:if>
<c:if test="${(empty task.status or task.status.code==0) and !task.enable}">
<a href="/task/enable/${task.id}">启用</a>
</c:if>
<c:if test="${(empty task.status or task.status.code==0)}">
<a href="/task/update/${task.id}">更新</a>
<a href="/task/delete/${task.id}">删除</a>
</c:if>
<c:if test="${task.status.code==1}">
<a href="/task/pause/${task.id}">暂停</a>
<a href="/task/stop/${task.id}">停止</a>
</c:if>
<c:if test="${task.status.code==2}">
<a href="/task/resume/${task.id}">恢复</a>
<a href="/task/stop/${task.id}">停止</a>
</c:if>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>

add.jsp

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
77
78
79
80
81
82
83
84
85
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>添加任务</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<%--<script src="/js/jquery-1.11.3.js" style="text/javascript"/>--%>
</head>
<body>
<form <c:choose><c:when test="${not empty task.id}">action="/task/update"</c:when>
<c:otherwise>action="/task/add"</c:otherwise></c:choose> method="post">
<input type="hidden" name="id" value="${task.id}">
<table>
<tr>
<td align = "center">任务名</td>
<td>
<input type="text" name="name" value="${task.name}">
</td>
</tr>
<tr>
<td align = "center">任务组</td>
<td>
<input type="text" name="group" value="${task.group}">
</td>
</tr>
<tr>
<td align = "center">源地址</td>
<td>
<select name="from.id" >
<c:forEach items="${nodes}" var="node" varStatus="vs">
<option value="${node.id }">
${node.name}
</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<td align = "center">源文件夹</td>
<td>
<input type="text" name="fromDir" value="${task.fromDir}">
</td>
</tr>
<tr>
<td align = "center">文件名</td>
<td>
<input type="text" name="fileName" value="${task.fileName}">
</td>
</tr>
<tr>
<td align = "center">目标文件夹</td>
<td>
<input type="text" name="toDir" value="${task.toDir}">
</td>
</tr>
<tr>
<td align = "center">执行时间表达式</td>
<td>
<input type="text" name="cronTime" value="${task.cronTime}">
</td>
</tr>
<tr>
<td align = "center">是否启用</td>
<td>
<input type="radio" name="enable" value="true" <c:if test="${task.enable}">checked="checked"</c:if>>是
<input type="radio" name="enable" value="false" <c:if test="${!task.enable}">checked="checked"</c:if>>否
</td>
</tr>
<tr>
<td align = "center">是否同步</td>
<td>
<input type="radio" name="sync" value="true" <c:if test="${task.sync}">checked="checked"</c:if>>是
<input type="radio" name="sync" value="false" <c:if test="${!task.sync}">checked="checked"</c:if>>否
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="确定">
</td>
</tr>
</table>
</form>
</body>
</html>

源码可以到LogMng下载,项目实现的是动态执行远程SSH复制文件任务,并支持任务的动态添加、删除、暂停、继续、停止等。

热评文章