zoukankan      html  css  js  c++  java
  • spring项目篇7----日志记录以及excel的插件poi的使用

    接下来为项目的后续进行功能以及访问分析提供数据支持,我们将访问记录存放到mysql,以便熟悉一下aop的道理。

    首先先建立我们的数据表

     使用mybatis插件生成pojo类以及映射文件

    在springmvc配置文件中进行切面的配置

    <!--日志处理类-->
        <bean id="systemAspect" class="com.yang.aspect.SystemAspect" />
        <!--aop配置-->
        <aop:config>
            <!--设置切入函数-->
            <aop:pointcut expression="execution(* com.yang.service.*.*(..))" id="servicePoint" />
            <!--切入位置-->
            <aop:aspect ref="systemAspect">
                <aop:after method="writeLog" pointcut-ref="servicePoint" />
            </aop:aspect>
        </aop:config>

    在进行存数据是,我们想到,ip地址在request中,但是在切面中是拿不到的,这个时候想到有一个本地线程可以使用,我们可以使用拦截器将本次访问的请求保存到本地线程中,然后再去从该线程中读取数据就可以,接下来先创建本地线程变量的读取request的工具类

    package com.yang.util;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * 读取request的本次线程工具类
     */
    public class RequestUtil {
        /*类属性,保证其唯一性*/
        public static ThreadLocal<HttpServletRequest> local = new ThreadLocal<>();
    
        /*获取request*/
        public static HttpServletRequest getRequest() {
            return local.get();
        }
    
        /*存储request*/
        public static void setRequest(HttpServletRequest request) {
            local.set(request);
            /**
             * 源码, 我们可以知道这个就是将该线程作为键,传入的reuqest作为值封装到map中
             * public void set(T value) {
             *         Thread t = Thread.currentThread();
             *         ThreadLocalMap map = getMap(t);
             *         if (map != null) {
             *             map.set(this, value);
             *         } else {
             *             createMap(t, value);
             *         }
             *     }
             */
        }
    }

    配置完成我们线程的存取request,接下来我们需要配置拦截器进行将拦截的request使用这个工具类存储到本地线程中

    package com.yang.interceptor;
    
    import com.yang.util.RequestUtil;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * request拦截器,继承HandlerInterceptor接口
     */
    public class RequestInterceptor implements HandlerInterceptor {
        /*只需要重写前置拦截*/
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 保存request
            RequestUtil.setRequest(request);
            return true;
        }
    }

    接下来我们需要在springmvc配置文件中配置一下,告知spring使用拦截器

        <!--配置拦截器-->
        <mvc:interceptors>
            <mvc:interceptor>
                <!--拦截所有请求-->
                <mvc:mapping path="/*" />
                <!--拦截器位置-->
                <bean class="com.yang.interceptor.RequestInterceptor" />
            </mvc:interceptor>
        </mvc:interceptors>

    接下来设置写入日志的切片方法

    package com.yang.aspect;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.yang.domain.Systemlog;
    import com.yang.mapper.SystemlogMapper;
    import com.yang.util.RequestUtil;
    import org.aspectj.lang.JoinPoint;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.Date;
    
    /**
     * 配置写入日志的类
     */
    public class SystemAspect {
    
        /*注入mapper*/
        @Autowired
        private SystemlogMapper systemlogMapper;
    
        /*处理写入日志的方法,切片会把切入点传进来,我们可以接受*/
        public void writeLog(JoinPoint point) throws JsonProcessingException {
            Systemlog systemlog = new Systemlog();
            // 设置日志
            systemlog.setOptime(new Date());
            // 设置request
            HttpServletRequest request = RequestUtil.getRequest();
            // 检测request是否为空,进行第一次授权的时候会先到realm中,不会先到拦截器中
            if (request != null) {
                // 设置ip
                systemlog.setIp(request.getRemoteAddr());
            }
            // 在切入点中获取类名
            String name = point.getTarget().getClass().getName();
            // 从切入点中获取签名
            String signature = point.getSignature().getName();
            // 设置函数名
            systemlog.setFunction(name + ":" + signature);
            // 获取参数,并序列化为字符串
            String params = new ObjectMapper().writeValueAsString(point.getArgs());
            // 设置参数
            systemlog.setParams(params);
            systemlogMapper.insert(systemlog);
        }
    }

    这个项目基本完成,接下来学习一下poi的使用,也就是导入导出excel文件。

    poi的简介:Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。

    poi官网文档:https://poi.apache.org/components/spreadsheet/quick-guide.html

    csdn的文章:https://www.cnblogs.com/huajiezh/p/5467821.html

    接下来在场景中用一下

    首先安装依赖,最新版本4.1.2,但是maven没下载下来,改为使用4.1.1

    <!--poi依赖,操纵excel文件-->
        <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>4.1.1</version>
        </dependency>

    直接在employee中使用导入导出,在jsp文件中设置两个按钮

    <a class="easyui-linkbutton" iconCls="icon-edit" id="import">导入</a>
    <a class="easyui-linkbutton" iconCls="icon-edit" id="export">导出</a>

    编写js文件

        /*监听下载按钮*/
        $('#export').click(function () {
            window.open("employee/download")
        });
    
        /*设置上传界面*/
        $('#upload').dialog({
            260,
            height:180,
            title:"导入Excel",
            buttons:[{
                text:"保存",
                handler:function () {
                    // 进行上传
                    $('#employUpload').form("submit", {
                        url:"employee/upload/file",
                        success:function (data) {
                            data = $.parseJSON(data);
                            if (data.success) {
                                $.messager.alert("提示", data.msg);
                                // 关闭上传
                                $('#upload').dialog("close");
                                // 重新加载数据表格
                                $("#dg").datagrid("reload");
                            } else {
                                $.messager.alert("温馨提示", data.msg);
                            }
                        }
                    })
                },
            },{
                text: "关闭",
                handler:function () {
                    $('#upload').dialog("close");
                }
            }],
            closed:true,
        });
        /*监听上传按钮*/
        $('#import').click(function () {
            $('#employUpload').form("clear");
            $('#upload').dialog("open");
        });
        /*监听下载模版按钮*/
        $('#downloadTemp').click(function () {
            window.open("employee/download/template")
    
        })

    如果想要上传文件,需要在springmvc的配置文件中配置一下文件上传解析器

        <!--配置文件上传解析器-->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!--设置上传最大文件大小-->
            <property name="maxUploadSize" value="10240000"/>
        </bean>

    编写控制层文件

        /*处理下载*/
        @RequestMapping("/employee/download")
        @ResponseBody
        public void downLoadEmployee(HttpServletResponse response) {
            // 首先获取所有的用户
            List<Employee> employees = employeeService.getAll();
            try {
                // 初始化一个工作簿
                HSSFWorkbook workbook = new HSSFWorkbook();
                // 新建一个sheet表
                HSSFSheet sheet = workbook.createSheet("员工数据");
                // 设置头部的行
                HSSFRow row = sheet.createRow(0);
                // 为每行设置字段
                row.createCell(0).setCellValue("编码");
                row.createCell(1).setCellValue("用户名");
                row.createCell(2).setCellValue("入职时间");
                row.createCell(3).setCellValue("电话");
                row.createCell(4).setCellValue("邮箱");
                row.createCell(5).setCellValue("是否在职");
                row.createCell(6).setCellValue("是否是管理员");
    
                // 开始设置信息
                // 不再循环中每次都初始化一行,在外面初始化
                HSSFRow employeeRow = null;
                for (int i = 0; i < employees.size(); i++) {
                    // 获取一个对象
                    Employee employee = employees.get(i);
                    // 创建一行
                    employeeRow = sheet.createRow(i + 1);
                    employeeRow.createCell(0).setCellValue(employee.getId());
                    employeeRow.createCell(1).setCellValue(employee.getUsername());
                    // 入职日期是时间格式,转化为字符串格式
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
                    String hireData = simpleDateFormat.format(employee.getHiredate());
                    // 设置入职日期
                    employeeRow.createCell(2).setCellValue(hireData);
                    employeeRow.createCell(3).setCellValue(employee.getPhone());
                    employeeRow.createCell(4).setCellValue(employee.getEmail());
                    employeeRow.createCell(5).setCellValue(employee.getState() ? "是" : "否");
                    employeeRow.createCell(6).setCellValue(employee.getAdmin() ? "是" : "否");
                }
                // 响应给浏览器
                // 设置文件名,iso8859-1需要设置
                String fineName = new String("员工数据.xls".getBytes(StandardCharsets.UTF_8), "iso8859-1");
                // 设置响应头为附件
                response.setHeader("content-Disposition", "attachment;filename=" + fineName);
                workbook.write(response.getOutputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /*处理下载员工模版*/
        @RequestMapping("/employee/download/template")
        @ResponseBody
        public void DownloadTemplate(HttpServletRequest request, HttpServletResponse response) {
            // 先声明一个文件流,最后关闭
            FileInputStream inputStream = null;
            // 获取文件路径
            String realPath = request.getSession().getServletContext().getRealPath("static/employeeTemp.xls");
            try {
                // 读取文件
                inputStream = new FileInputStream(realPath);
                // 响应给浏览器
                // 设置文件名,iso8859-1需要设置
                String fineName = new String("employeeTemp.xls".getBytes(StandardCharsets.UTF_8), "iso8859-1");
                // 设置响应头为附件
                response.setHeader("content-Disposition", "attachment;filename=" + fineName);
                IOUtils.copy(inputStream, response.getOutputStream());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 如果文件流不为空,则关闭
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /*进行文件上传*/
        @RequestMapping("/employee/upload/file")
        @ResponseBody
        public AjaxRes uploadEmployee(MultipartFile excel) {
            AjaxRes ajaxRes = new AjaxRes();
            try {
                // 将上传的文件作为流传入
                HSSFWorkbook workbook = new HSSFWorkbook(excel.getInputStream());
                // 获取第一张工作表,因为模版中只规定创建第一张工作表
                HSSFSheet sheet = workbook.getSheetAt(0);
                // 获取最大行号
                int lastRowNum = sheet.getLastRowNum();
                HSSFRow employeeRow = null;
                for (int i = 1; i <= lastRowNum; i++) {
                    Employee employee = new Employee();
                    employeeRow = sheet.getRow(i);
                    // 设置用户名
                    employee.setUsername((String) getCellValue(employeeRow.getCell(1)));
                    // 设置入职时间
                    employee.setHiredate((Date) getCellValue(employeeRow.getCell(2)));
                    // 设置电话,因为11为返回的数字是double,科学技术,我们选转化为BigDecimal然后再转化为字符串
                    double phone = (double) getCellValue(employeeRow.getCell(3));
                    BigDecimal phoneDecimal = new BigDecimal(String.valueOf(phone));
                    employee.setPhone(phoneDecimal.toPlainString());
                    // 设置邮箱
                    employee.setEmail((String) getCellValue(employeeRow.getCell(4)));
                    // 设置是否在职
                    String employeeState = (String) getCellValue(employeeRow.getCell(5));
                    employee.setState(employeeState.equals("否"));
                    // 设置是否是管理员
                    String admin = (String) getCellValue(employeeRow.getCell(6));
                    employee.setAdmin(admin.equals("是"));
                    // 设置初始密码 1234
                    employee.setPassword("1234");
                    employeeService.insertEmployeeInExcel(employee);
                    ajaxRes.setSuccess(true);
                    ajaxRes.setMsg("导入成功!");
                }
            } catch (IOException e) {
                e.printStackTrace();
                ajaxRes.setSuccess(false);
                ajaxRes.setMsg("导入失败!");
            }
            return ajaxRes;
        }
    
        /*设置处理每一行类型的函数*/
        private Object getCellValue(Cell cell) {
            switch (cell.getCellType()) {
                case STRING:
                    return cell.getRichStringCellValue().getString();
                case NUMERIC:
                    // 判断是否时间
                    if (DateUtil.isCellDateFormatted(cell)) {
                        return cell.getDateCellValue();
                    } else {
                        return cell.getNumericCellValue();
                    }
                case BOOLEAN:
                    return cell.getBooleanCellValue();
                case FORMULA:
                    return cell.getCellFormula();
            }
            return cell;
        }

    到现在为止,这个简单的权限小项目完成了。源码地址github:https://github.com/yang-shixiong/springDemo/tree/master/permissionPro

     

  • 相关阅读:
    机器学习算法
    消息队列
    net core 静态文件
    Startup 和 Middleware(中间件)
    HLS 协议
    Web APIs 基于令牌TOKEN验证的实现
    cyq.data开源
    FluentConsole是一个托管在github的C#开源组件
    数据层全栈式编程架构
    Java NIO 完全学习笔记(转)
  • 原文地址:https://www.cnblogs.com/yangshixiong/p/12323267.html
Copyright © 2011-2022 走看看