springboot项目模板
https://blog.csdn.net/j_guangxin/article/details/78498191
一、配置文件
#下面这条配置声明了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
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
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>
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>
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(); } }
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 // https://blog.csdn.net/moshowgame/article/details/80275084 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 }
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 }
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>
目录
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>时钟能力中心</title>
<script type="text/javascript" th:src= "@{/{path}static/js/jquery.min.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap.min.js(path=${contextPath})}"></script>
<link th:href="@{/{path}static/js/font-awesome-4.7.0/css/font-awesome.css(path=${contextPath})}" rel="stylesheet" type="text/css">
<link th:href="@{/{path}static/js/bootstrap.min.css(path=${contextPath})}" rel="stylesheet" type="text/css">
<link th:href="@{/{path}static/js/bootstrap-3.3.7/dist/css/bootstrap.css(path=${contextPath})}" rel="stylesheet" type="text/css">
<!-- table -->
<link th:href="@{/{path}static/js/bootstrap-table-develop/dist/bootstrap-table.css(path=${contextPath})}" rel="stylesheet" type="text/css">
<link th:href="@{/{path}static/js/bootstrap-table-develop/dist/bootstrap-table.min.css(path=${contextPath})}" rel="stylesheet" type="text/css">
<link th:href="@{/{path}static/js/bootstrap-table-develop/dist/extensions/fixed-columns/bootstrap-table-fixed-columns.css(path=${contextPath})}" rel="stylesheet" type="text/css">
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap-table-develop/dist/bootstrap-table.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap-table-develop/dist/locale/bootstrap-table-zh-CN.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap-table-develop/dist/extensions/resizable/bootstrap-table-resizable.min.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap-table-develop/dist/bootstrap-table.min.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap-table-develop/dist/extensions/accent-neutralise/bootstrap-table-accent-neutralise.min.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap-table-develop/dist/extensions/fixed-columns/bootstrap-table-fixed-columns.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/table/tableExport.min.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/bootstrap-table-develop/dist/extensions/export/bootstrap-table-export.min.js(path=${contextPath})}"></script>
<script type="text/javascript" th:src= "@{/{path}static/js/toastr/toastr.min.js(path=${contextPath})}"></script>
<link th:href="@{/{path}static/js/toastr/toastr.min.css(path=${contextPath})}" rel="stylesheet" type="text/css">
<script type="text/javascript">
<!-- 获取项目名称 -->
var projectname = "[[@{/}]]";
projectname = projectname.split("/")[1];
projectname = "/"+projectname;
</script>
<style type="text/css">
html body{
width:90%;
height:100%;
margin: 0 auto;
}
</style>
</head>
<body>
</body>
</html>
配置文件
配置文件中添加:::
#静态资源文件访问
#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
登录处理
持久层接口
用例图