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({
        width: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

 

posted @ 2020-02-17 19:55  灬灬灬灬灬灬  阅读(461)  评论(0编辑  收藏  举报