标签:required ip地址 工具 control syn .project login ast document
easyui+springboot+jpa实现一个简单的后台管理系统
1.首先,添加依赖,配置yml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.32</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
</dependency>
</dependencies>
yml:
server: port: 8081 servlet: context-path: / spring: http: encoding: force: true charset: UTF-8 freemarker: suffix: .ftl cache: false request-context-attribute: request charset: UTF-8 template-loader-path: classpath:/view/ check-template-location: false profiles: active: config mvc: static-path-pattern: /static/** datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://xx.xxx.xxx:3306/game?useUnicode=true&characterEncoding=UTF-8mb4&useSSL=false username: xxx password: xxx jpa: database: mysql show-sql: true
整体的截图:

static里面放的是静态资源,yml里static-path-pattern是配置了静态资源的路径
inc文件夹中放置了inc.ftl 调用了一些样式,方便其他页面的调用静态资源
inc.ftl:
<script src="${request.contextPath}/static/jquery/jquery.min.js"></script>
<script src="${request.contextPath}/static/jquery/jquery.form.js"></script>
<!--easyui -->
<!-- easyui.css放前面 -->
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/default/easyui.css" rel="stylesheet" title="default">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/black/easyui.css" rel="stylesheet" title="black">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/bootstrap/easyui.css" rel="stylesheet" title="bootstrap">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/gray/easyui.css" rel="stylesheet" title="gray">
<link rel="stylesheet" type="text/css" href="${request.contextPath}/static/easyui/themes/styles/metro/easyui.css" rel="stylesheet" title="metro">
<link rel="stylesheet" href="${request.contextPath}/static/easyui/themes/icon.css" />
<link rel="stylesheet" href="${request.contextPath}/static/easyui/themes/color.css" />
<script src="${request.contextPath}/static/easyui/jquery.easyui.min.js"></script>
<script src="${request.contextPath}/static/easyui/datagrid-detailview.js"></script>
<script src="${request.contextPath}/static/easyui/easyui-lang-zh_CN.js"></script>
<script src="${request.contextPath}/static/easyui/extEasyUI.js" charset="utf-8"></script>
<script src="${request.contextPath}/static/jquery/jquery.serializejson.js"></script>
<#--<!--自定义样式 –>-->
<link rel="stylesheet" href="${request.contextPath}/static/manager/css/global.css" />
<script src="${request.contextPath}/static/manager/js/global.js"></script>
<link rel="stylesheet" href="${request.contextPath}/static/manager/css/img.css" />
<script src="${request.contextPath}/static/manager/js/img.js"></script>
其他页面只需要在<head>中加入
<#include "inc/inc.ftl"/>,就能调用和inc一样的静态资源
2.完成登陆/修改密码/退出系统的功能和工具类/页面的编写
login.ftl就不放了
index.ftl:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>ace Admin</title>
<meta name="description" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<#include "inc/inc.ftl"/>
</head>
<body>
<div id="test"></div>
<div class="easyui-layout" data-options="fit:true">
<div data-options="region:‘north‘" class="head_body" style="overflow:hidden;">
<div>
<div class="head_left"></div>
<div class="head_right">
<div class="huanying">
欢迎 <span>${Session.userInfo.username}</span> 登陆 | 现在是<span id="show_date"></span>
</div>
<div class="anniu">
<div class="bb">
<a href="javascript:logout();" class="logout"></a>
<a id="open_change_password" class="changePwd" href="javascript:editPassword();"></a>
</div>
<div class="bs">
<a class="styleswitch a1" style="CURSOR: pointer" title="黑灰色" rel="black"></a>
<a class="styleswitch a2" style="CURSOR: pointer" title="天蓝色" rel="default"></a>
<a class="styleswitch a3" style="CURSOR: pointer" title="灰色" rel="bootstrap"></a>
<a class="styleswitch a4" style="CURSOR: pointer" title="浅灰色" rel="gray"></a>
<a class="styleswitch a5" style="CURSOR: pointer" title="白色" rel="metro"></a>
</div>
</div>
</div>
</div>
</div>
<div data-options="region:‘west‘,split:true,title:‘导航菜单‘" style="width:188px;">
<div class="easyui-accordion" id="main-accordion" data-options="fit:true,border:false">
<ul>
<li><a href="javascript:void(0)" class="easyui-linkbutton"
onclick="addTab(‘设置一级权重‘,‘resources/to_setting‘)">设置一级权重</a></li>
<li><a href="javascript:void(0)" class="easyui-linkbutton"
onclick="addTab(‘设置二级权重‘,‘resources/to_detailSetting‘)">设置二级权重</a></li>
<li><a href="javascript:void(0)" class="easyui-linkbutton"
onclick="addTab(‘设置游戏道具‘,‘resources/to_gameProp‘)">设置游戏道具</a></li>
</ul>
</div>
</div>
<div id="mainPanel" data-options="region:‘center‘">
<div id="index_tabs" class="easyui-tabs" data-options="fit:true,border:false,tabHeight:30"
style="height:600px;">
<div title="Home">
<div style="padding:10px 0 10px 10px">
<h2>系统介绍</h2>
<div class="light-info">
</div>
</div>
</div>
</div>
</div>
</div>
<div id="dlg" class="easyui-dialog" style="width:450px;height:auto;padding:10px 20px" buttons="#dlg-buttons"
data-options="closed:true,modal:true">
<form id="fm" method="post" enctype="multipart/form-data">
<input type="hidden" id="userId" name="userId"/>
<table class="grid">
<tr>
<td>请输入新密码:</td>
<td>
<input type="text" name="password" class="easyui-passwordbox" iconWidth="28"
data-options="required:true,validType:[‘length[0,20]‘]"/>
</td>
</tr>
</table>
</form>
</div>
<div id="dlg-buttons">
<a href="javascript:void(0)" class="easyui-linkbutton c8" data-options="iconCls:‘icon-ok‘"
onclick="javascript:saveUser();" style="width:90px;">保存</a>
<a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:‘icon-cancel‘"
onclick="javascript:$(‘#dlg‘).dialog(‘close‘);" style="width:90px;">取消</a>
</div>
</body>
</html>
<script type="text/javascript">
$(document).ready(function () {
var myDate = new Date();
var week = [‘日‘, ‘一‘, ‘二‘, ‘三‘, ‘四‘, ‘五‘, ‘六‘];
var month = myDate.getMonth() + 1;
var weekDay = " 星期" + week[myDate.getDay()];
var showDate = myDate.getFullYear() + "年" + month + "月" + myDate.getDate() + "日" + weekDay;
$("#show_date").text(showDate);
});
//初始化TABS组件
$(‘#index_tabs‘).tabs({
fit: true,
border: false,
tabHeight: 30,
tools: [{
iconCls: ‘icon-reload‘,
handler: function () {
var currTab = $(‘#index_tabs‘).tabs(‘getSelected‘);
var index = $(‘#index_tabs‘).tabs(‘getTabIndex‘, currTab);
if (index != 0) {
var updateUrl = $(currTab.panel(‘options‘).content).attr(‘src‘);
$(‘#index_tabs‘).tabs(‘update‘, {
tab: currTab,
options: {
content: refreshTab(updateUrl)
}
});
}
}
}, {
iconCls: ‘icon-clear‘,
handler: function () {
$.messager.confirm(‘提示‘, ‘确定要全部关闭选项卡?‘, function (r) {
if (r) {
var tabTitle = new Array();
var tabs = $(‘#index_tabs‘).tabs("tabs");
var tCount = tabs.length;
if (tCount > 0) {
for (var i = 0; i < tCount; i++) {
tabTitle.push(tabs[i].panel(‘options‘).title);
}
for (var i = 0; i < tabTitle.length; i++) {
if (tabTitle[i] != ‘首页‘) {
$(‘#index_tabs‘).tabs("close", tabTitle[i]);
}
}
}
}
});
}
}]
});
function editPassword() {
$(‘#dlg‘).dialog(‘open‘).dialog(‘setTitle‘, ‘修改‘);
$("#userId").val(${Session.userInfo.id});
}
function saveUser() {
$(‘#fm‘).form(‘submit‘, {
url: "${request.contextPath}/user_save",
success: function (result) {
var result = eval(‘(‘ + result + ‘)‘);
if (result.code == 0) {
$.messager.show({
title: ‘提示‘,
msg: result.message
});
$(‘#dlg‘).dialog(‘close‘);
}
}
});
}
</script>
页面截图:

登陆/修改密码/退出系统功能的控制层:
package com.yz.slotsgameht.controller; import com.yz.slotsgameht.domain.SysUser; import com.yz.slotsgameht.service.SysUserService; import com.yz.slotsgameht.utils.GetIpAddress; import com.yz.slotsgameht.utils.Result; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * @Author: Lukizzz * @Date: 2018/8/28 14:19 * @Description: */ @Controller public class SysUserController { private final Logger log = LoggerFactory.getLogger(SysUser.class); @Autowired private SysUserService sysUserService; @RequestMapping("/login") public String login2() { return "login"; } @RequestMapping(value = "/do_login") public String login(String username, String password, HttpServletRequest request) { SysUser user = sysUserService.getUserByLogin(username); HttpSession session = request.getSession(); String xIp = GetIpAddress.getIpAddress(request); log.info("账号: {},密码: {},本地ip:{}", username, password, xIp); if (user == null) { request.setAttribute("errorInfo", "用户名不存在"); return "login"; } else if (user.getPassword().equals(password)) {
//将获取的user数据存入session中,名字为"userInfo" session.setAttribute("userInfo", user); return "redirect:/index"; } else { request.setAttribute("errorInfo", "用户名密码错误"); return "login"; } } @RequestMapping(value = "/logout") public String logout(HttpServletRequest request) { HttpSession session = request.getSession(); session.removeAttribute("userInfo"); return "login"; } @RequestMapping(value = "/index") public String index() { return "index"; } @RequestMapping(value = "/user_save") @ResponseBody public Result saveUser(Long userId,String password,HttpServletRequest request){
//获取ip地址 String ip = GetIpAddress.getIpAddress(request);
//日志 log.info("新密码: {},本地ip地址:{}", password, ip); sysUserService.saveUser(userId, password); return Result.builder(); } }
Result工具类:
package com.yz.slotsgameht.utils; import lombok.Data; /** * @Author: Lukizzz * @Date: 2018/8/29 16:02 * @Description: */ @Data public class Result<T> { private int code = 0; private String message; private T data; private CodeMsg codeMsg = CodeMsg.SUCCESS; public static Result builder(CodeMsg codeMsg) { Result result = new Result(); result.setCode(codeMsg.getCode()); result.setMessage(codeMsg.getMsg()); return result; } public static Result builder() { return builder(CodeMsg.SUCCESS); } public Result withCode(CodeMsg codeMsg) { message = codeMsg.getMsg(); code = codeMsg.getCode(); return this; } public Result withData(T data) { this.data = data; return this; } public Result() { this.code = codeMsg.getCode(); this.message = codeMsg.getMsg(); } public Result(CodeMsg codeMsg) { this.code = codeMsg.getCode(); this.message = codeMsg.getMsg(); } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } public void setCodeMsg(CodeMsg codeMsg) { this.codeMsg = codeMsg; } }
CodeMsg工具类:
package com.yz.slotsgameht.utils; /** * @author admin * @date 2017/8/24 */ public enum CodeMsg { SUCCESS(0, "成功"), FAIL(1, "未知错误"), USER_PWD_ERROR(1000, "用户名密码错误"), CHANNEL_EXIST(1001, "已存在此代理渠道"), SUBCHANNEL_EXIST(1002, "已存此在渠道"), USERNAME_EXIST(1003, "此用户名已存在"), UID_NOT_EXIST(1004, "UID不存在"), FID_NOT_EXIST(1005, "FID不存在"), ANCHOR_NOT_EXIST(1006, "主播不存在"), BOTTOM(10000000, "垫底"); private int code; private String msg; CodeMsg(int code, String msg) { this.code = code; this.msg = msg; } public int getCode() { return code; } public String getMsg() { return msg; } }
从Http中解析request获取ip地址
package com.yz.slotsgameht.utils; import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; /** * @Author: Lukizzz * @Date: 2018/8/30 10:13 * @Description: */ public class GetIpAddress { public static String getIpAddress(HttpServletRequest request) { String ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) { // 根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } ipAddress = inet.getHostAddress(); } } if (ipAddress != null && ipAddress.length() > 15) { if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } return ipAddress; } }
3.修改游戏设置功能(以修改道具名称和兑换金币为例)
控制层:
package com.yz.slotsgameht.controller; import com.yz.slotsgameht.domain.AppGameProp; import com.yz.slotsgameht.domain.AppProbabilitySetting; import com.yz.slotsgameht.service.AppGamePropService; import com.yz.slotsgameht.utils.GetIpAddress; import com.yz.slotsgameht.utils.Result; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.util.List; /** * @Author: Lukizzz * @Date: 2018/8/31 11:45 * @Description: */ @RestController @RequestMapping(value = "/prop") public class AppGamePropController { private final Logger log = LoggerFactory.getLogger(AppProbabilitySetting.class); @Autowired private AppGamePropService appGamePropService; @RequestMapping(value ="/findPropList" ) public List<AppGameProp> findPropList(){ return appGamePropService.findPropList(); } @RequestMapping(value = "editNameSave") public Result editNameSave(Long id, String name, HttpServletRequest request){ String ip = GetIpAddress.getIpAddress(request); log.info("修改名称的id: {},新名称: {},本地ip地址:{}", id, name, ip); appGamePropService.editNameSave(id, name); return new Result(); } @RequestMapping(value = "editGoldNumSave") public Result editGoldNumSave(Long id, Integer goldNum,HttpServletRequest request){ String ip = GetIpAddress.getIpAddress(request); log.info("修改兑换金币的id: {},新兑换金币数量: {},本地ip地址:{}", id, goldNum, ip); appGamePropService.editGoldNumSave(id, goldNum); return new Result(); } }
上面的代码中有一点需要注意:datagrid传输的数据是json,因为这边还有一个查找的功能,所以在控制层需要加上@responsebody注解或是将@controller注解变成@restcontroller,里面也包含了@responsebody的注解
业务逻辑层:
package com.yz.slotsgameht.service; import com.yz.slotsgameht.dao.AppGamePropDAO; import com.yz.slotsgameht.domain.AppGameProp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @Author: Lukizzz * @Date: 2018/8/31 11:48 * @Description: */ @Service public class AppGamePropService { @Autowired private AppGamePropDAO appGamePropDAO; public List<AppGameProp> findPropList(){ return appGamePropDAO.findAll(); } public void editNameSave(Long id,String name){ appGamePropDAO.updateNameById(id,name); } public void editGoldNumSave(Long id,Integer goldNum){ appGamePropDAO.updateGoldNumById(id,goldNum); } }
数据访问层:
package com.yz.slotsgameht.dao; import com.yz.slotsgameht.domain.AppGameProp; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; /** * @Author: Lukizzz * @Date: 2018/8/31 11:48 * @Description: */ public interface AppGamePropDAO extends JpaRepository<AppGameProp,Long> { /** * 修改道具名称 * @param id * @param name */ @Transactional(rollbackFor = Exception.class) @Modifying @Query(value = "update app_game_prop u set u.name = :name where u.id = :id", nativeQuery = true) void updateNameById(@Param(value = "id") Long id, @Param(value = "name") String name); /** * 修改兑换金币 * @param id * @param goldNum */ @Transactional(rollbackFor = Exception.class) @Modifying @Query(value = "update app_game_prop set gold_num = :goldNum where id = :id", nativeQuery = true) void updateGoldNumById(@Param(value = "id") Long id, @Param(value = "goldNum") Integer goldNum); }
这边也需要注意一点是:因为功能是修改update,所以不需要返回数据,在service层和DAO都使用void
附上这个功能ftl的代码和相关截图:
<!DOCTYPE html> <html> <head> <#include "inc/inc.ftl"/> </head> <body> <div class="easyui-layout" data-options="fit:true,border:false"> <table id="dg"></table> </div> <div id="toolbar" style="padding:5px;height:auto"> <div> <a onclick="editName();" href="javascript:void(0);" class="easyui-linkbutton" data-options="plain:true,iconCls:‘icon-edit‘">修改道具名称</a> <a onclick="editGoldNum();" href="javascript:void(0);" class="easyui-linkbutton" data-options="plain:true,iconCls:‘icon-edit‘">修改兑换金币数</a> </div> </div> <div id="dlg_edit" class="easyui-dialog" style="width:400px;height:auto;padding:10px 20px" buttons="#dlg-buttons_edit1" data-options="closed:true,modal:true"> <form id="fm_edit" method="post" enctype="multipart/form-data"> <input type="hidden" id="id1" name="id"/> 请输入新名称: <input class="easyui-textbox" data-options="prompt:‘请输入新的道具名称‘" style="width:50%;height:32px" name="name"> </form> </div> <div id="dlg-buttons_edit1"> <a href="javascript:void(0)" class="easyui-linkbutton c8" data-options="iconCls:‘icon-ok‘" onclick="javascript:editNameSave();" style="width:90px;">保存</a> <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:‘icon-cancel‘" onclick="javascript:$(‘#dlg_edit‘).dialog(‘close‘);" style="width:90px;">取消</a> </div> <div id="dlg_editNum" class="easyui-dialog" style="width:400px;height:auto;padding:10px 20px" buttons="#dlg-buttons_edit2" data-options="closed:true,modal:true"> <form id="fm_editNum" method="post" enctype="multipart/form-data"> <input type="hidden" id="id2" name="id"/> 请输入兑换金币数: <input class="easyui-textbox" data-options="prompt:‘请输入兑换金币数‘" style="width:50%;height:32px" name="goldNum"> </form> </div> <div id="dlg-buttons_edit2"> <a href="javascript:void(0)" class="easyui-linkbutton c8" data-options="iconCls:‘icon-ok‘" onclick="javascript:editGoldNumSave();" style="width:90px;">保存</a> <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:‘icon-cancel‘" onclick="javascript:$(‘#dlg_editNum‘).dialog(‘close‘);" style="width:90px;">取消</a> </div> </body> </html> <script type="text/javascript"> $(document).ready(function () { loadData(); }); function loadData() { $("#dg").datagrid({ url: ‘${request.contextPath}/prop/findPropList‘, striped: true, border: false, collapsible: false, //是否可折叠的 loadMsg: ‘正在加载数据...‘, idField: ‘id‘, fit: true, //自动大小 singleSelect: true,//是否单选 pagination: true,//分页控件 pageSize: 20, columns: [[{ field: ‘name‘, title: ‘道具名称‘, width: 150, align: ‘center‘ }, { field: ‘goldNum‘, title: ‘兑换金币数‘, width: 150, align: ‘center‘ }, { field: ‘propType‘, title: ‘所属元素‘, width: 150, align: ‘center‘ }]], toolbar: ‘#toolbar‘ }); } function editName() { var row = $(‘#dg‘).datagrid(‘getSelected‘); if (row) { $(‘#fm_edit‘).form(‘load‘, row); $(‘#dlg_edit‘).dialog(‘open‘).dialog(‘setTitle‘, ‘修改‘); } else { $.messager.alert("提示", "请选择一条记录"); } } function editNameSave() { $(‘#fm_edit‘).form(‘submit‘, { url: "${request.contextPath}/prop/editNameSave", success: function (result) { var result = eval(‘(‘ + result + ‘)‘); if (result.code == 0) { $(‘#dg‘).datagrid(‘reload‘); $(‘#dlg_edit‘).dialog(‘close‘); } else { $.messager.show({ title: ‘提示‘, msg: result.message }); } } }); } function editGoldNum() { var row = $(‘#dg‘).datagrid(‘getSelected‘); if (row) { $(‘#fm_editNum‘).form(‘load‘, row); $(‘#dlg_editNum‘).dialog(‘open‘).dialog(‘setTitle‘, ‘修改‘); } else { $.messager.alert("提示", "请选择一条记录"); } } function editGoldNumSave() { $(‘#fm_editNum‘).form(‘submit‘, { url: "${request.contextPath}/prop/editGoldNumSave", success: function (result) { var result = eval(‘(‘ + result + ‘)‘); if (result.code == 0) { $(‘#dg‘).datagrid(‘reload‘); $(‘#dlg_editNum‘).dialog(‘close‘); } else { $.messager.show({ title: ‘提示‘, msg: result.message }); } } }); } </script>


在日志配置的时候,要添加一个配置文件
网上应该有很多:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration scan="true">
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<!-- The FILE and ASYNC appenders are here as examples for a production configuration -->
<property name="PROJECT" value="hnuser" />
<property name="ROOT" value="logs/" />
<property name="FILESIZE" value="10MB" />
<property name="MAXHISTORY" value="3" />
<timestamp key="DATETIME" datePattern="yyyy-MM-dd HH:mm:ss" />
<!-- ERROR 输入到文件,按日期和文件大小 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/error.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- WARN 输入到文件,按日期和文件大小 -->
<appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/warn.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- INFO 输入到文件,按日期和文件大小 -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/info.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- DEBUG 输入到文件,按日期和文件大小 -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/debug.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- Logger 根目录 -->
<root level="INFO">
<appender-ref ref="DEBUG" />
<appender-ref ref="ERROR" />
<appender-ref ref="WARN" />
<appender-ref ref="INFO" />
</root>
<logger name="javax.activation" level="WARN"/>
<logger name="javax.mail" level="WARN"/>
<logger name="javax.management.remote" level="WARN"/>
<logger name="javax.xml.bind" level="WARN"/>
<logger name="ch.qos.logback" level="WARN"/>
<logger name="com.codahale.metrics" level="WARN"/>
<logger name="com.netflix" level="WARN"/>
<logger name="com.netflix.discovery" level="INFO"/>
<logger name="com.ryantenney" level="WARN"/>
<logger name="com.sun" level="WARN"/>
<logger name="com.zaxxer" level="WARN"/>
<logger name="io.undertow" level="WARN"/>
<logger name="io.undertow.websockets.jsr" level="ERROR"/>
<logger name="org.ehcache" level="WARN"/>
<logger name="org.apache" level="WARN"/>
<logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/>
<logger name="org.bson" level="WARN"/>
<logger name="org.hibernate.validator" level="WARN"/>
<logger name="org.hibernate" level="WARN"/>
<logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
<logger name="org.springframework" level="WARN"/>
<logger name="org.springframework.web" level="WARN"/>
<logger name="org.springframework.security" level="WARN"/>
<logger name="org.springframework.cache" level="WARN"/>
<logger name="org.thymeleaf" level="WARN"/>
<logger name="org.xnio" level="WARN"/>
<logger name="springfox" level="WARN"/>
<logger name="sun.rmi" level="WARN"/>
<logger name="liquibase" level="WARN"/>
<logger name="LiquibaseSchemaResolver" level="INFO"/>
<logger name="sun.net.www" level="INFO"/>
<logger name="sun.rmi.transport" level="WARN"/>
<!-- https://logback.qos.ch/manual/configuration.html#shutdownHook and https://jira.qos.ch/browse/LOGBACK-1090 -->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
</configuration>
也别忘了在控制层引入
private final Logger log = LoggerFactory.getLogger(SysUser.class);
标签:required ip地址 工具 control syn .project login ast document
原文地址:https://www.cnblogs.com/Lukizzz/p/9582473.html