• 随笔9


    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&amp;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>
    
    <#--<!--自定义样式  &ndash;&gt;-->
    <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="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="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="90px;">保存</a>
        <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
           onclick="javascript:$('#dlg').dialog('close');" style="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="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="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="90px;">保存</a>
        <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
           onclick="javascript:$('#dlg_edit').dialog('close');" style="90px;">取消</a>
    </div>
    
    <div id="dlg_editNum" class="easyui-dialog" style="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="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="90px;">保存</a>
        <a href="javascript:void(0)" class="easyui-linkbutton c2" data-options="iconCls:'icon-cancel'"
           onclick="javascript:$('#dlg_editNum').dialog('close');" style="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: '道具名称',
                     150,
                    align: 'center'
                }, {
                    field: 'goldNum',
                    title: '兑换金币数',
                     150,
                    align: 'center'
                }, {
                    field: 'propType',
                    title: '所属元素',
                     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);
  • 相关阅读:
    phpcms后台进入地址(包含No permission resources错误)
    phpmyadmin上传大sql文件办法
    ubuntu彻底卸载mysql
    Hdoj 2602.Bone Collector 题解
    一篇看懂词向量
    Hdoj 1905.Pseudoprime numbers 题解
    The Python Challenge 谜题全解(持续更新)
    Hdoj 2289.Cup 题解
    Hdoj 2899.Strange fuction 题解
    Hdoj 2199.Can you solve this equation? 题解
  • 原文地址:https://www.cnblogs.com/Lukizzz/p/9582473.html
Copyright © 2020-2023  润新知