一、配置文件
#下面这条配置声明了mybatis的配置文件路径,classpath对应的是和这个文件统计的resources
mybatis.config-location=classpath:mybatis-config.xml
#静态资源文件访问
#spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/static/js/**
# default location: src/main/webapp , can be changed
# old version
spring.mvc.view.prefix=/WEB-INF/page
spring.mvc.view.suffix=.jsp
# new version
#spring.view.prefix=/
#spring.view.suffix=.jsp
# thymeleaf
spring.thymeleaf.prefix=/WEB-INF/page
spring.thymeleaf.suffix=.jsp
#测试 参数的调用
com.didispace.blog.name=程序员
com.didispace.blog.title=SpringBoot
com.didispace.blog.desc=${com.didispace.blog.name} is writting 《${com.didispace.blog.title}》
#设置编码
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8
#多环境配置文件属性
spring.profiles.active=test
# 设置项目名称
server.servlet.context-path=/clockck
# 多项目部署
spring.jmx.enabled=false
application.properties
1 # test environment
2 server.port=8080
3
4
5 #mysql
6 spring.datasource.url=jdbc:mysql://10.188.191.2:3306/tianhu?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
7 spring.datasource.username=root
8 spring.datasource.password=110120
9 spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
10 spring.jpa.database = mysql
11
12 #Mybatis扫描(配置xml模式使用) mybatis.mapper-locations=classpath*:mapper/*.xml
13 #起别名。可省略写mybatis的xml中的resultType的全路径
14 mybatis.type-aliases-package=cn.th.jump.demoboot.bean
15
16 #连接池配置信息
17 spring.datasource.max-wait=10000
18 spring.datasource.max-active=50
19 spring.datasource.max-idle=10
20 spring.datasource.min-idle=8
21 spring.datasource.test-on-borrow=true
22 spring.datasource.validation-query=select 1
23 spring.datasource.initialPoolSize=3
24 spring.datasource.maxPoolSize=20
25 spring.datasource.idleConnectionTestPeriod = 10
application-test.properties
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
5 <configuration>
6
7 <settings>
8 <!-- Globally enables or disables any caches configured in any mapper under this configuration -->
9 <setting name="cacheEnabled" value="true"/>
10 <!-- Sets the number of seconds the driver will wait for a response from the database -->
11 <setting name="defaultStatementTimeout" value="3000"/>
12 <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn -->
13 <setting name="mapUnderscoreToCamelCase" value="true"/>
14 <!-- Allows JDBC support for generated keys. A compatible driver is required.
15 This setting forces generated keys to be used if set to true,
16 as some drivers deny compatibility but still work -->
17 <setting name="useGeneratedKeys" value="true"/>
18 </settings>
19
20 <!-- Continue going here -->
21
22 </configuration>
mybatis-config.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--debug="true" : 打印logback内部状态(默认当logback运行出错时才会打印内部状态 ),配置该属性后打印条件如下(同时满足):
3 1、找到配置文件 2、配置文件是一个格式正确的xml文件 也可编程实现打印内部状态,例如: LoggerContext lc = (LoggerContext)
4 LoggerFactory.getILoggerFactory(); StatusPrinter.print(lc); -->
5 <!-- scan="true" : 自动扫描该配置文件,若有修改则重新加载该配置文件 -->
6 <!-- scanPeriod="30 seconds" : 配置自动扫面时间间隔(单位可以是:milliseconds, seconds, minutes
7 or hours,默认为:milliseconds), 默认为1分钟,scan="true"时该配置才会生效 -->
8 <configuration debug="false" scan="true" scanPeriod="30 seconds" packagingData="true">
9 <!-- 设置 logger context 名称,一旦设置不可改变,默认为default -->
10 <contextName>clocksys</contextName>
11
12 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
13 <!-- encoders are by default assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
14 <encoder>
15 <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
16 </encoder>
17 </appender>
18
19 <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
20 <!-- 当前活动日志文件名 -->
21 <file>./clockck_log.log</file> <!-- ./clocksys_log.log -->
22 <!-- 文件滚动策略根据%d{patter}中的“patter”而定,此处为每天产生一个文件 -->
23 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
24 <!-- 归档文件名“.zip或.gz结尾”,表示归档文件自动压缩 -->
25 <FileNamePattern>./clockck_log%d{yyyyMMdd}.log.zip</FileNamePattern>
26 <maxHistory>30</maxHistory>
27 </rollingPolicy>
28
29 <!--rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
30 <fileNamePattern>renhai%i.log</fileNamePattern>
31 <minIndex>1</minIndex>
32 <maxIndex>10</maxIndex>
33 </rollingPolicy>
34
35 <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
36 <maxFileSize>20MB</maxFileSize>
37 </triggeringPolicy-->
38
39 <!-- <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
40 rollover daily
41 <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
42 each file should be at most 30MB, keep 60 days worth of history, but at most 20GB
43 <maxFileSize>30MB</maxFileSize>
44 <maxHistory>60</maxHistory>
45 <totalSizeCap>20GB</totalSizeCap>
46 </rollingPolicy> -->
47
48
49 <encoder>
50 <pattern>%d{HH:mm:ss.SSS}[%-5level][%thread]%logger{36} - %msg%n</pattern>
51 <!-- <pattern>%d{HH:mm:ss.SSS}[%-5level][%thread] - %msg%n</pattern> -->
52 </encoder>
53 </appender>
54
55 <!-- 日志级别若没显示定义,则继承最近的父logger(该logger需显示定义level,直到rootLogger)的日志级别-->
56 <!-- logger的appender默认具有累加性(默认日志输出到当前logger的appender和所有祖先logger的appender中),可通过配置 “additivity”属性修改默认行为-->
57 <logger name="com.yinz" level="INFO" additivity="false" >
58 <appender-ref ref="FILE"/>
59 <appender-ref ref="STDOUT" />
60 </logger>
61
62 <!-- 至多只能配置一个root -->
63 <root level="ERROR">
64 <appender-ref ref="STDOUT" />
65 <appender-ref ref="FILE" />
66 </root>
67 </configuration>
logback.xml
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>Clock Test PlatForm</title>
6 <script type="text/javascript" th:src= "@{/{path}static/js/jquery-1.8.3-min.js(path=${contextPath})}"></script>
7 <script type="text/javascript" th:src= "@{/{path}static/js/jquery.min.js(path=${contextPath})}"></script>
8 <script type="text/javascript" th:src= "@{/{path}static/js/bootstrap.min.js(path=${contextPath})}"></script>
9 <link th:href="@{/{path}static/js/font-awesome-4.7.0/css/font-awesome.css(path=${contextPath})}" rel="stylesheet" type="text/css">
10 <link th:href="@{/{path}static/js/bootstrap.min.css(path=${contextPath})}" rel="stylesheet" type="text/css">
11
12 <link href="https://unpkg.com/bootstrap-table@1.14.1/dist/bootstrap-table.min.css" rel="stylesheet">
13 <script src="https://unpkg.com/bootstrap-table@1.14.1/dist/bootstrap-table.min.js"></script>
14 <script src="https://unpkg.com/bootstrap-table@1.14.1/dist/extensions/accent-neutralise/bootstrap-table-accent-neutralise.min.js"></script>
15
16 <style>
17 html,
18 body{
19 margin: 0;
20 padding: 0;
21 width: 100%;
22 height: 100%;
23 overflow-y: auto;
24 }
25 .container{
26 width:100%;
27 height:100%;
28 margin:0 auto;
29 }
30 .box{
31 width:100%;
32 height:100%;
33 text-align: center;
34 }
35 .header{
36 width:100%;
37 height:8%;
38 line-height:200%;
39 font-size: x-large;
40 font-weight: bold;
41 font-family: 宋体;
42 }
43 .content{
44 position:relative;
45 width:100%;
46 height:100%;
47 margin:0 auto;
48 }
49 .content_body{
50 position: relative;
51 height:95%;
52 }
53 .content_left{
54 height:100%;
55 width:20%;
56 float:left;
57 }
58 .content_right{
59 height:100%;
60 width:80%;
61 float:right;
62 }
63 </style>
64 </head>
65 <body style="width: 100%; height: 100%">
66 <script type="text/javascript">
67 <!-- 获取项目名称 -->
68 var projectname = "[[@{/}]]";
69 projectname = projectname.split("/")[1];
70 projectname = "/"+projectname;
静态资源引用示例
二、关于WebSocket的使用
package cn.th.jump.demoboot.controller;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* 在打包运行在外部服务器时,将该类中的@Configuration\ @Bean 注解去掉
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
WebSocketConfig
1 package cn.th.jump.demoboot.controller;
2 import java.io.IOException;
3 import java.util.concurrent.CopyOnWriteArraySet;
4
5 import javax.websocket.OnClose;
6 import javax.websocket.OnError;
7 import javax.websocket.OnMessage;
8 import javax.websocket.OnOpen;
9 import javax.websocket.Session;
10 import javax.websocket.server.PathParam;
11 import javax.websocket.server.ServerEndpoint;
12 import org.springframework.stereotype.Component;
13 import cn.hutool.log.Log;
14 import cn.hutool.log.LogFactory;
15
16
17 @ServerEndpoint("/websocket")
18 @Component
19 public class WebSocketServer {
20
21 //
22
23 static Log log=LogFactory.get(WebSocketServer.class);
24 //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
25 private static int onlineCount = 0;
26 //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
27 private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
28
29 //与某个客户端的连接会话,需要通过它来给客户端发送数据
30 private Session session;
31
32 //接收sid
33 private String sid="";
34 /**
35 * 连接建立成功调用的方法*/
36 @OnOpen
37 public void onOpen(Session session,@PathParam("sid") String sid) {
38 this.session = session;
39 webSocketSet.add(this); //加入set中
40 addOnlineCount(); //在线数加1
41 //log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());
42 this.sid=sid;
43 try {
44 sendMessage("连接成功");
45 } catch (IOException e) {
46 log.error("websocket IO异常");
47 }
48 }
49
50 /**
51 * 连接关闭调用的方法
52 */
53 @OnClose
54 public void onClose() {
55 webSocketSet.remove(this); //从set中删除
56 subOnlineCount(); //在线数减1
57 log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
58 }
59
60 /**
61 * 收到客户端消息后调用的方法
62 *
63 * @param message 客户端发送过来的消息*/
64 @OnMessage
65 public void onMessage(String message, Session session) {
66 log.info("收到来自窗口"+sid+"的信息:"+message);
67 //群发消息
68 for (WebSocketServer item : webSocketSet) {
69 try {
70 item.sendMessage(message);
71 } catch (IOException e) {
72 e.printStackTrace();
73 }
74 }
75 }
76
77 /**
78 *
79 * @param session
80 * @param error
81 */
82 @OnError
83 public void onError(Session session, Throwable error) {
84 log.error("发生错误");
85 error.printStackTrace();
86 }
87 /**
88 * 实现服务器主动推送
89 */
90 public void sendMessage(String message) throws IOException {
91 //this.session.getBasicRemote().sendText(message);
92 this.session.getBasicRemote().sendText(message);
93 }
94
95
96 /**
97 * 群发自定义消息
98 * */
99 public static void sendInfo(String message) throws IOException {
100 log.info("推送消息到窗口 "+message,message);
101 for (WebSocketServer item : webSocketSet) {
102 try {
103 //这里可以设定只推送给这个sid的,为null则全部推送
104 item.sendMessage(message);
105 } catch (IOException e) {
106 continue;
107 }
108 }
109 }
110
111 public static synchronized int getOnlineCount() {
112 return onlineCount;
113 }
114
115 public static synchronized void addOnlineCount() {
116 WebSocketServer.onlineCount++;
117 }
118
119 public static synchronized void subOnlineCount() {
120 WebSocketServer.onlineCount--;
121 }
122 }
WebSocketServer
1 package cn.th.jump.demoboot;
2
3 import org.mybatis.spring.annotation.MapperScan;
4 import org.springframework.boot.SpringApplication;
5 import org.springframework.boot.autoconfigure.SpringBootApplication;
6 import org.springframework.boot.builder.SpringApplicationBuilder;
7 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
8 import org.springframework.scheduling.annotation.EnableScheduling;
9 import org.springframework.transaction.annotation.EnableTransactionManagement;
10
11 //@Configuration
12 //@ComponentScan
13 //@EnableTransactionManagement
14
15 @EnableScheduling // 允许开启定时任务
16 @SpringBootApplication // 此注解替代上述三个注解
17 @EnableTransactionManagement // 开启事务支持
18 @MapperScan(basePackages = "cn.th.jump.demoboot.dao")
19 public class DemobootApplication extends SpringBootServletInitializer {
20
21 public static void main(String[] args) {
22 SpringApplication.run(DemobootApplication.class, args);
23 }
24
25 @Override
26 protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
27 return builder.sources(DemobootApplication.class);
28 }
29 }
DemobootApplication
1 <script type="text/javascript">
2 <!-- 获取项目名称 -->
3 var projectname = "[[@{/}]]";
4 projectname = projectname.split("/")[1];
5 projectname = "/"+projectname;
6
7 <!-- websocket -->
8 var socket;
9 if(typeof(WebSocket) == "undefined") {
10 console.log("您的浏览器不支持WebSocket");
11 }else{
12 console.log("您的浏览器支持WebSocket");
13
14 var linkUrl = "ws://localhost:8080"+ projectname +"/websocket".replace("http","ws");
15 socket = new WebSocket(linkUrl);
16
17 //打开事件
18 socket.onopen = function() {
19 console.log("clockchecker Socket 已打开");
20 };
21
22 //获得消息事件
23 socket.onmessage = function(msg) {
24 handleOutcoming(msg.data)
25 };
26
27 //关闭事件
28 socket.onclose = function() {
29 console.log("Socket已关闭");
30 };
31
32 //发生了错误事件
33 socket.onerror = function() {
34 alert("Socket发生了错误");
35 }
36 }
37 <!-- ^^^^^^^^^websocket^^^^^^^^^ -->
38
39 </script>
jsp端调用
目录
配置文件
配置文件中添加:::
#静态资源文件访问
#spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/static/img/**
# default location: src/main/webapp , can be changed
# old version
spring.mvc.view.prefix=/WEB-INF/page
spring.mvc.view.suffix=.jsp
# new version
#spring.view.prefix=/
#spring.view.suffix=.jsp
# thymeleaf
spring.thymeleaf.prefix=/WEB-INF/page
spring.thymeleaf.suffix=.jsp
登录处理
持久层接口
用例图