目 录CONTENT

文章目录

学习笔记(杂用)(一)

筱晶哥哥
2021-01-27 / 0 评论 / 0 点赞 / 27 阅读 / 105659 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2024-03-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

本篇文章主要记录本人学习过程中的一些小干货。

idea中的文件最好别随意移动到别的文件夹中,最好是复制到文件夹中,否则会有别的目录中的文件引用这个文件的东西的话,会全部改掉相关东西,导致崩盘!!!

Thymeleaf模板中,html如何获取session中的值

后台控制器中代码:

request.getSession().setAttribute("uname", "lijing");

前端页面中代码:

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试</title>
</head>
<body>
    <span th:text="${session.uname}"></span>
</body>
</html>

Springboot2.3中文乱码解决

Springboot1.x解决http请求中文乱码的方法网上很常见,一搜一大堆,大概就是以下三步骤:

spring.http.encoding.charset=UTF-8
spring.http.encoding.force=true
spring.http.encoding.enabled=true

奈何,我使用的开发的Springboot版本为2.X,这类注解已经被标注过期了。那怎么解决呢?

翻看springboot的官方文档,毕竟相信权威嘛。

访问地址:Springboot官方文档

打开首页,通过encoding关键字全文搜索,可知springboot使用了新的配置方式:

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
server.servlet.encoding.enabled=true

SpringBoot项目实现热部署的配置方法

什么是SpringBoot热部署?

SpringBoot热部署就是在项目正在运行的时候修改代码, 却不需要重新启动项目。

有了SpringBoot热部署后大大提高了开发效率,因为频繁的重启项目,势必会浪费很多时间, 有了热部署后,妈妈再也不用担心我修改代码重启项目了。

SpringBoot热部署的流程

pom文件中导入 spring-boot-devtools 依赖:

(或者创建springboot工程时,勾选devtools选项,会自动在pom中加入依赖)

<!--SpringBoot热部署配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

继续在pom.xml中添加插件:

<build>
     <plugins>
     <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <!--SpringBoot热部署时配置 -->
         <configuration>
          <fork>true</fork>
                  <addResources>true</addResources>
         </configuration>
         <!--SpringBoot热部署时配置 -->
    </plugin>
     </plugins>
</build>

设置application.properties

#配置项目热部署
spring.devtools.restart.enabled=true

在idea中设置自动编译

1.打开Settings,设置当前项目自动编译,搜索Compiler,勾选Build project automatically

2.打开Other Settings ,设置新建的项目都自动编译,搜索Compliler,勾选Build project automatically

3.按住ctrl + shift + alt + /,出现如下图所示界面,点击Registry...

4.点击进入后,勾选compiler.automake.allow.when.app.running后关闭即可

通过以上步骤,就完成了SpringBoot项目的热部署功能!!!

springboot项目中无法直接访问templates下的html文件的解决方法

解决方案是在appliation.properties下添加

#表明静态资源的位置,默认值是classpath:/static/
spring.resources.static-locations=classpath:/templates/

表明静态资源的位置,即可直接访问。

因为默认情况下,浏览器可以通过url访问springboot的静态资源(static中的文件),访问不到templates中的html。

如果将静态资源目录指定为templates,就可以访问了。

也可以将templates中的html文件移到static目录下,这样就可以直接访问html文件了。

不建议这样做,不应该让浏览器直接访问到html文件。而是通过控制器跳转访问。

thymeleaf疑问

今天在学习thymeleaf的时候,对resources文件夹下的几个子文件夹产生了一些疑问(static、templates),最后通过验证,发现在外部浏览器中只能访问到static文件夹下的资源(static意味静态的),而templates模板文件夹下的文件不可直接被访问,如html等。

templates文件夹下的文件(不,应该是除static以外的文件夹下的文件)都是通过视图解析器访问的,springboot默认static文件夹之外的页面需要通过controller访问(好像是websecurity权限控制)

总结:springboot项目,static文件夹下的静态资源可以直接通过url访问,而templates文件夹下的文件只能通过视图解析器访问,除非手动指定静态资源的位置。

Vue引入jquery和bootstrap

安装bootstarp之前,要先安装jquery:

npm install jquery --save

安装Bootstrap:

npm install bootstrap --save #(一定要查看bootstrap的版本,到bootstrap官网去查看对应版本用法)
npm install --save popper.js

在main.js中加入:

/*引入jquery以及bootstrap*/
import jquery from 'jquery'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'

Vue.prototype.$=jquery /*使用Vue挂载jquery*/

编写bootstrap相关代码,看是否成功!

(我这里配置的是vue-cli4.x + bootstrap4.x)

Spring Boot项目中配置favicon&配置favicon无效解决

关闭favicon

在application.properties中设置关闭favicon

#默认为true,高版本此配置已经过期
spring.mvc.favicon.enabled=false

设置自定义favicon

只需要将自己的favicon.ico放在(即项目默认就有的resourses目录)类路径META-INF/resources/下,或类路径resources/下、或类路径static/下,或类路径public/下。

可以在这个网站进行自行制作:favicon制作

添加无效解决

如果添加无效,在浏览器中不显示,就在需要在页面中head标签添加以下代码
我这里是使用了Thymeleaf模板的html:

<head>
  <meta charset="UTF-8">
  <title>登录页面</title>
  <link rel="shortcut icon" th:href="@{/favicon.ico}"/>
  <link rel="bookmark" th:href="@{/favicon.ico}"/>
</head>

其他页面模板可以使用:

<head>
   <meta charset="UTF-8">
   <title>登录页面</title>
   <link rel="shortcut icon" href="/favicon.ico"/>
   <link rel="bookmark" href="/favicon.ico"/>
</head> 

我就是这么设置,好像一个页面设置就行了,我访问项目其他页面也有,浏览器貌似有缓存的样子。

Mysql创建create_time跟update_time字段,使其自动存值

创建语句如下:

ALTER TABLE table_name
ADD COLUMN create_time timestamp NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN update_time timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER create_time;

MySQL按日期分组统计(按天统计,按月统计)

以下为您演示MySQL常用的日期分组统计方法:

按月统计(一)

select date_format(create_time, '%Y-%m') mont, count(*) coun
from t_content
group by date_format(create_time, '%Y-%m');

按天统计(二)

select date_format(create_time, '%Y-%m-%d') dat, count(*) coun
from t_content
group by date_format(create_time, '%Y-%m-%d');

其他用法

create_time时间戳格式

SELECT FROM_UNIXTIME(create_time,'%Y%u') weeks,COUNT(id) COUNT FROM role GROUP BY weeks SELECT FROM_UNIXTIME(create_time,'%Y%m%d') days,COUNT(id) COUNT FROM role GROUP BY days SELECT FROM_UNIXTIME(create_time,'%Y%m') months,COUNT(id) COUNT FROM role GROUP BY months 

create_time时间格式

SELECT DATE_FORMAT(create_time,'%Y%u') weeks,COUNT(id) COUNT FROM role GROUP BY weeks   SELECT DATE_FORMAT(create_time,'%Y%m%d') days,COUNT(id) COUNT FROM role GROUP BY days   SELECT DATE_FORMAT(create_time,'%Y%m') months,COUNT(id) COUNT FROM role GROUP BY months 

mysql数据库操作时报模式(sql_mode)错误解决方法

Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'information_schema.PROFILING.SEQ' which  is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

原因:这是数据库的sql_mode设置的有问题。Mysql可以支持不同的SQL模式,不同的SQL模式会有不同的语法,执行不同的数据校验简查。

首先,可以先查看一下数据库现在的sql_mode的值,sql语句为:

select version(), @@sql_mode; 

然后可以使用如下语句,去设置自己需要的sql_mode:

SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

jQuery表格排序插件

引用文件

--js:

<script src="js/jquery-1.11.1.min.js"></script> 
<script src="js/jquery.dataTables.js"></script>

--css

<link rel="stylesheet" href="css/jquery.dataTables.css" />

代码:

<html>
 <head></head>
 <body>
  <div class="TabBox">
    <table class="data-table" width="100%">
      <thead>
        <tr>
          <th class="nosort">Rendering engine</th>
          <th>Browser</th>
          <th>Platform(s)</th>
          <th>Engine version</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Trident</td>
          <td>Internet
            Explorer 4.0</td>
          <td>Win 95+</td>
          <td>4</td>
        </tr>
        <tr>
          <td>Trident</td>
          <td>Internet
            Explorer 5.0</td>
          <td>Win 95+</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Trident</td>
          <td>Internet
            Explorer 5.5</td>
          <td>Win 95+</td>
          <td>5.5</td>
        </tr>
        <tr>
          <td>Trident</td>
          <td>Internet
            Explorer 6</td>
          <td>Win 98+</td>
          <td>6</td>
        </tr>
      </tbody>
    </table>
</div><!--TabBox-->
<script>
$(document).ready(function(){
    $('.data-table').dataTable({
        "searching": false,  //是否允许Datatables开启本地搜索
        "paging": false,  //是否开启本地分页
        "lengthChange": false,  //是否允许用户改变表格每页显示的记录数
        "info": false,   //控制是否显示表格左下角的信息
        "columnDefs": [{
            "targets": 'nosort',  //列的样式名
            "orderable": false    //包含上样式名‘nosort’的禁止排序
        }],
        //跟数组下标一样,第一列从0开始,这里表格初始化时,第四列默认降序
        "order": [3]  //asc升序   desc降序  "order": [[ 3, "desc" ]]默认第四列为降序排列
    });
});
</script>
</body>
</html>

如果某一列不需要排序,在标签上加上class=“nosort”

thymeleaf格式化日期格式

<td th:text="${#dates.format(fund.netWorthDate,'yyyy-MM-dd')}"></td>

云服务器dubbo报错解决方法

在做项目时,突然报了:

Caused by: com.alibaba.dubbo.remoting.RemotingException: message can not send, because channel is closed

这样的异常,经过查资料,大概知道了是由于IP引发的,解决方法是重启云服务器。

java中thymeleaf获取项目根路径

<a th:href="${#httpServletRequest.getContextPath()}"></a>

Thymeleaf 内置对象 之 获取web应用根路径

今天使用Thymeleaf模板引擎想要获取WEB应用根目录,那么thymeleaf中是不是和JSP中一样有request内置对象呢,没错,果然就有,废话不多说,上代码:

<!--getScheme()获取协议,getServerName()获取服务器名,getServerPort()服务器端口,getContextPath() APP根路径-->
<a th:href="${#httpServletRequest.getScheme() + '://' + #httpServletRequest.getServerName() + ':' + #request.getServerPort()  + #request.getContextPath() + '/'} "
 id="contextPath"></a>
<script>
$(function () {
    var contextPath = $('#contextPath').attr('href');//获取应用的根目录,我的绝对路径是http://localhost:8080/
});
</script>

例如写个注册功能:

<script type="text/javascript" th:inline="javascript">
    function toRegist() {
        var scheme = [[${#httpServletRequest.getScheme()}]]
        var severname = [[${#httpServletRequest.getServerName()}]]
        var port = [[${#request.getServerPort()}]]
        var path = [[${#request.getContextPath()}]];
        var cxt = scheme + "://" + severname + ":" + port + path + "/"
        location.href = cxt + "user/toRegist"
    }
</script>

按钮点击事件跳转根路径下任意路径:

<script type="text/javascript" th:inline="javascript">
    function to(addr) {
        var scheme = [[${#httpServletRequest.getScheme()}]]
        var severname = [[${#httpServletRequest.getServerName()}]]
        var port = [[${#request.getServerPort()}]]
        var path = [[${#request.getContextPath()}]];
        var cxt = scheme + "://" + severname + ":" + port + path + "/"
        location.href = cxt + addr
    }
</script>

表单验证

function testPhone() {
    var phone = $("#phone").val();
    if (phone == "" || phone == "请输入11位手机号码") {
        $("#showPhone").html("请输入11位手机号码");
        return false;
    }

    if (!/^1[1-9]\d{9}$/.test(phone)) {
        $("#showPhone").html("请输入正确的手机号");
        return false;
    }
    $("#showPhone").html("");
    return true;
}

function testPassword() {
    var loginPassword = $("#loginPassword").val();
    if (loginPassword == "" || loginPassword == "请输入登录密码") {
        $("#showPassword").html("请输入登录密码");
        return false;
    }
    if (loginPassword.length < 6 || loginPassword.length > 16) {
        $("#showPassword").html("密码为6到16位");
        return false;
    }
    $("#showPassword").html("");
    return true;
}

//用户登录
function Login() {
    if (testPhone() != true || testPassword() != true) {
        console.log("no")
        return false
    }
    console.log("yes")
    return true
}

在表单上加onsubmit时间句柄,实现在表单提交前验证,返回false则不提交。

语法:return 函数名()

<form action="/test/login" method="post" onsubmit="return Login()"> </form>

springboot 整合shiro无法访问静态资源的问题

最近在学springboot 整合shiro后发现无法访问静态资源

springboot默认把所有的静态资源都映射到static目录了

在使用shiro功能时候,发现静态资源全部被拦截了,所以要配置信息对静态资源进行放行。

在ShiroConfig中添加:

filterChainMap.put("/images/**", "anon");//静态images资源放行
filterChainMap.put("/css/**", "anon");//静态css资源放行
filterChainMap.put("/js/**", "anon");//静态js资源放行

这样就可以访问了。

springboot+thymeleaf实现自定义错误页面

在templates目录下新建error目录,在error目录下添加错误页面即可。

报错:ids for this class must be manually assigned before calling save(),解决方法

在实体类的id上加上主键生成策略:

@GeneratedValue(strategy = GenerationType.IDENTITY)/*主键生成策略*/

layui弹窗倒计时

//layer.msg弹窗倒计时
//second : 倒计时时间,单位,秒
//content: 弹窗内容,类型;String
function countDown(second,content){
    layer.msg(content, {
        time : second*1000,
        shade: 0.6,
        success: function(layero,index){
            var msg = layero.text();
            var i = second;
            var timer = null;
            var fn = function() {
                layero.find(".layui-layer-content").text(msg+' '+i+'秒后跳转到登录页面!');
                if(!i) {
                    layer.close(index);
                    clearInterval(timer);
                }
                i--;
            };
            timer = setInterval(fn, 1000);
            fn();
        },
    }, function() {
        location.href = "/"
    });
}

PageHelper分页的相关方法

public void test(){
   PageHelper.startPage(1, 5); //分页核心语句
   ArrayList<Users> list = userDao.getUserList();
   PageInfo<Users> page = new PageInfo<Users>(list);
   System.out.println("总数量:" + page.getTotal());
   System.out.println("当前页查询记录:" + page.getList().size());
   System.out.println("当前页码:" + page.getPageNum());
   System.out.println("每页显示数量:" + page.getPageSize());
   System.out.println("总页:" + page.getPages());
}

thymeleaf添加点击事件

<a id="update" href="" th:onclick="findById([[${fund.id}]])">修改</a>

springboot集成swagger2

加入依赖:

<!--Swigger2配置-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

编写swagger2配置文件:

package com.easyfund.springboot.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/*swagger2配置*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    /**
     * 是否开启swagger
     */
    @Value("${swagger.enabled}")
    private boolean enabled;

    /**
     * 创建API
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                // 是否启用Swagger
                .enable(enabled)
                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
                .apiInfo(apiInfo())
                // 设置哪些接口暴露给Swagger展示
                .select()
                // 扫描指定包中的swagger注解
                .apis(RequestHandlerSelectors.basePackage("com.easyfund.springboot.controller"))
                // 扫描所有 .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 添加摘要信息
     */
    private ApiInfo apiInfo() {
        // 用ApiInfoBuilder进行定制
        return new ApiInfoBuilder()
                // 设置标题
                .title("易基金管理系统_接口文档")
                // 描述
                .description("描述:用于管理易基金下的基金信息、用户信息等.....")
                // 作者信息
                .contact(new Contact("李晶", "http://xiaojinggege.gitee.io/xiaojingge/", "2427259171@qq.com"))
                // 版本
                .version("版本号:" + "1.0.0.RELEASE")
                .build();
    }
}

在sprinboot主配置文件中开启swagger2配置:

#swagger2配置
swagger.enabled=true

shiro放行swagger2访问页面:

        /*swagger2免拦截*/
        filterChainMap.put("/swagger-ui.html**", "anon");
        filterChainMap.put("/v2/api-docs", "anon");
        filterChainMap.put("/swagger-resources/**", "anon");
        filterChainMap.put("/webjars/**", "anon");

layui表格日期格式化

 {field: 'netWorthDate', title: '净值日期', align: 'center', width: 150, sort: true,templet: "<div>{{layui.util.toDateString(d.netWorthDate, 'yyyy-MM-dd HH:mm:ss')}}</div>"}

layui表格分页显示

https://www.jianshu.com/p/a42820440cfb

之前在练习layui的时候,遇到表格数据需要分页显示的,总是天真的以为要从数据库中取出全部数据,再在页面进行分页操作,其实应该将分页的代码操作在后台进行实现(其实之前都是在后台操作,只不过刚刚接触layui,天真以为它什么都帮我干了 哈哈)。

弄懂这件事之后,我在网上查了大量的文章,但多数都是以自己的业务需求出发的想法,多数照着弄都实现不了,很纠结,对于有代码洁癖的我来说,坚决认为layui还是能强大到不用额外的js和jquery代码,就能实现这个功能,而且不需要定义其他的除表格本身以外的其他div,就能将分页模块插进去(其实layui-table就自带了开启分页功能,真心想不懂还要另外的地方插入分页模块),那么我就将折磨了我一下午的layui-table自带的分页功能以我的视角,给大家展示一下我的代码,希望能对初学者的大家有那么一点点帮助。
layui表格分页访问后台时,会自动传递page和limit参数。

页面的表格区域:

<table class="layui-hide" id="demo" lay-filter="test"></table>

layui的表格实例:(主要看limit和page这两个参数的写法)

//执行一个 table 实例

  table.render({

    elem: '#demo'//表格table的id属性

    ,height: 420

    ,url: '${pageContext.request.contextPath}/students/students' //请求数据接口

    ,limit:5//要传向后台的每页显示条数
    //,page:true(自带的这个要注掉)
   ,page: { //支持传入 laypage 组件的所有参数(某些参数除外,如:jump/elem) - 详见文档
        layout: ['count', 'prev', 'page', 'next', 'limit', 'refresh', 'skip']//自定义分页布局 
        ,limits:[5,10,15]
        ,first: false //不显示首页
        ,last: false //不显示尾页
      }

    ,title: '用户表'

    ,toolbar: 'default' //开启工具栏,此处显示默认图标,可以自定义模板,详见文档

    ,cols: [[ //表头

      {type: 'checkbox', fixed: 'left'}

      ,{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left', totalRowText: '合计:'}

      ,{field: 'name', title: '用户名', width:80}

      ,{field: 'sex', title: '性别', width:80,}   

      ,{field: 'city', title: '城市', width:100} 

      ,{field: 'email', title: '邮箱', width: 150}

      ,{field: 'major', title: '专业', width: 80}

      ,{field: 'score', title: '成绩', width: 80, sort: true}

      ,{field: 'sign', title: '备注', width: 200}

      ,{fixed: 'right', width: 165, align:'center', toolbar: '#barDemo'}

    ]]
  });

后台:controller

@ResponseBody//可以把一个集合转为json返回给前端
@RequestMapping(value = "students")
//注意参数的名字要与前端对应(当然你自己制定名字也行,这里就默认用它的参数名字接手了)
public Map<String,Object> showStudents(int page, int limit) throws IOException{
         //获取全部学生信息
        List<Students> students = studentsService.getStudents();
         //获取分页后的每页学生信息
        List<Students> student = studentsService.getStudentsCount(page,limit); 
        
        Map<String,Object> tableData =new HashMap<String,Object>();
        //这是layui要求返回的json数据格式
        tableData.put("code", 0);
        tableData.put("msg", "");
        //将全部数据的条数作为count传给前台(一共多少条)
        tableData.put("count", students.size());
        //将分页后的数据返回(每页要显示的数据)
        tableData.put("data", student);
        //返回给前端
        return tableData;
}

Spring data JPA 控制台打印sql

#控制台打印sql配置
spring.jpa.show-sql=true

layui日期时间选择器

<div class="layui-inline">
        <label class="layui-form-label">日期时间选择器</label>
        <div class="layui-input-inline">
            <input type="text" class="layui-input" id="mydate" placeholder="yyyy-MM-dd HH:mm:ss">
        </div>
    </div>


<script>
layui.use('laydate', function(){
  var laydate = layui.laydate;

    //日期时间选择器
  laydate.render({
    elem: '#mydate'
    ,type: 'datetime'
  });
    
});
</script>
    

springboot配置mybatis打印sql语句

#mybatis打印sql语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

springboot写入数据库汉字变问号???

用spring boot做的项目,后台向数据库中写入汉字,变成了问号,但是后台确实是向数据库中传递的汉字,数据库也是使用的utf8编码,怎么回事?
检查一下spring boot和数据库中的连接问题:
在application.properties里面的数据库连接中加入:

&useUnicode=true&characterEncoding=UTF-8

比方说我的数据库连接加入上面这一行之后变成:

spring.datasource.url=jdbc:mysql://47.94.217.177:3306/easyFund?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8

layui表格添加数据自动刷新

table.reload('LAY-fund-manage'); //数据刷新,LAY-fund-manage为表格的id

layui批量获取数据表格中的数据并传到后台进行解析

pom文件加依赖:

<!--通过Json类把json数组解析成集合对象-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.35</version>
        </dependency>

前端ajax请求(array是一个数组对象):

$.ajax({
    url: '/admin/fundBatchDelete',
    data: {
        data: JSON.stringify(array) //传递json格式的字符串到后台
    },
    type: 'post',
    dateType: 'json',
    success: function (result) {
        if (result > 0) {
            table.reload('LAY-fund-manage');
            layer.msg('已删除', {icon: 1, time: 1000});
        } else {
            layer.msg('出了点小问题', {icon: 2, time: 2000});
        }
    }
})

后台代码(举例):

/*批量删除基金信息*/
    @RequestMapping("/fundBatchDelete")
    @ResponseBody
    public Integer fundBatchDelete(String data) {
        System.out.println(data);
        /*后台解析json数据*/
        List<Integer> fundIds = JSON.parseArray(data, int.class);//解析成集合对象
        int result = fundBiz.batchDeleteFund(fundIds);
        return result;
    }

thymeleaf模板引擎templates目录中的html文件引入static目录中的静态样式

<!--第一种方式,使用thymeleaf标签-->
<link rel="stylesheet" th:href="@{/css/style.css}">
<script th:src="@{/js/layui.js}"></script>

<!--第二种方式,这样写会默认从static下找文件-->
<link rel="stylesheet" href="./css/style.css">
<script src="./js/layui.js"></script>

阿里云实现实名认证

pom文件导入依赖:

 <!--通过Json类把json数组解析成集合对象-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.35</version>
        </dependency>

        <!--实名认证所需依赖-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>9.3.7.v20160115</version>
        </dependency>

具体实现类:

package com.easyfund.springboot.util;

import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lijing
 * @Description
 * @create 2020-09-17 9:38
 */
public class RealNameUtils {

    public static void main(String[] args) {
        String host = "https://idenauthen.market.alicloudapi.com";
        String path = "/idenAuthentication";
        String method = "POST";
        String appcode = "你的appcode";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求,定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("idNo", "320723199702255613");
        bodys.put("name", "李晶");


        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

工具类HttpUtils:

package com.easyfund.springboot.util;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author lijing
 * @Description
 * @create 2020-09-17 9:43
 */
public class HttpUtils {
    /**
     * get
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doGet(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpGet request = new HttpGet(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        return httpClient.execute(request);
    }

    /**
     * post form
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param bodys
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      Map<String, String> bodys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (bodys != null) {
            List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();

            for (String key : bodys.keySet()) {
                nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
            }
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
            request.setEntity(formEntity);
        }

        return httpClient.execute(request);
    }

    /**
     * Post String
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }

        return httpClient.execute(request);
    }

    /**
     * Post stream
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }

        return httpClient.execute(request);
    }

    /**
     * Put String
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }

        return httpClient.execute(request);
    }

    /**
     * Put stream
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }

        return httpClient.execute(request);
    }

    /**
     * Delete
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doDelete(String host, String path, String method,
                                        Map<String, String> headers,
                                        Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);

        HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }

        return httpClient.execute(request);
    }

    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (!StringUtils.isBlank(path)) {
            sbUrl.append(path);
        }
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String, String> query : querys.entrySet()) {
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
                    sbQuery.append(query.getValue());
                }
                if (!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if (!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }
        }

        return sbUrl.toString();
    }

    private static HttpClient wrapClient(String host) {
        HttpClient httpClient = new DefaultHttpClient();
        if (host.startsWith("https://")) {
            sslClient(httpClient);
        }

        return httpClient;
    }

    private static void sslClient(HttpClient httpClient) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] xcs, String str) {

                }

                public void checkServerTrusted(X509Certificate[] xcs, String str) {

                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry registry = ccm.getSchemeRegistry();
            registry.register(new Scheme("https", 443, ssf));
        } catch (KeyManagementException ex) {
            throw new RuntimeException(ex);
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }
}

返回数据格式:

{
    "name":"李晶",
    "idNo":"320723199702255613",
    "respMessage":"身份证信息匹配",
    "respCode":"0000",
    "province":"江苏省",
    "city":"连云港市",
    "county":"灌云县",
    "birthday":"19970225",
    "sex":"M",
    "age":"23"
}

使用LayUI进行文件上传(带预览功能)

参考文章:使用LayUI进行文件上传(带预览功能)

1、添加LayUI上传组件需要的js文件

jquery.min.js、layui.all.js、layer.js

2、导入上传组件jar包

commons-fileupload、commons-io

3、在spring配置文件中限制上传文件的大小,否则会报错

<!-- 设置上传文件最大值   1M=1*1024*1024(B)=1048576 bytes -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="1048576" />
</bean>xxxxxxxxxx <!-- 设置上传文件最大值   1M=1*1024*1024(B)=1048576 bytes -->

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
    <property name="maxUploadSize" value="1048576" />
</bean><!-- 设置上传文件最大值   1M=1*1024*1024(B)=1048576 bytes -->

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
    <property name="maxUploadSize" value="1048576" />
</bean>

4、前端页面代码

<div class="layui-upload">
  <button type="button" class="layui-btn" id="test1">上传图片</button>
  <div class="layui-upload-list">
    <img class="layui-upload-img" id="previewImg">
    <p id="demoText"></p>
  </div>
</div>

5、js代码

<script type="text/javascript">
    //图片上传
    layui.use('upload', function(){
        var $ = layui.jquery
            ,upload = layui.upload;
        //普通图片上传
        var uploadInst = upload.render({
            elem: '#test1'
            ,url: '/uploadImages'
            ,before: function(obj){
                //预读本地文件示例,不支持ie8
                obj.preview(function(index, file, result){                  
                    $('#previewImg').attr('src', result); //图片链接(base64)
                });
            }
            ,done: function(res){
                //上传失败
                if(res.code > 0){
                    return layer.msg('上传失败');
                }
                //上传成功,返回的路径:res.filePath
            }
            ,error: function(){
                //上传失败
                return layer.msg('上传失败,请重试!');
            }
        });
    });
</script>

6、后台java代码

/**
 * 文件上传
 * @param file
 * @param request
 * @param response
 * @return
 * @throws Exception
 */
@RequestMapping(value = "/uploadImages",method=RequestMethod.POST)
@ResponseBody
public WebUploadResult uploadImages(MultipartFile file,HttpServletRequest request, HttpServletResponse response) throws Exception {
    String destDir = "/upload/picture";
    WebUploadResult webResult = new WebUploadResult();
    try {
        String path = WebUpload.uploads(file, destDir, request,response);
        webResult.setStatus(0);
        webResult.setFilePath(path);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return webResult;
}

7、工具类

WebUpload.java类:

import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class WebUpload {
    private static String suffixStrs = "bmp|jpg|png|tiff|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF";

    public static String uploads(MultipartFile file, String destDir, HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        //获取文件上传的真实路径
        String uploadPath = request.getSession().getServletContext().getRealPath("/");
        try {
            //判断上传文件的后缀
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
            if (suffixStrs.indexOf(suffix) == -1) {
                throw new Exception("上传文件格式不正确");
            }
            //保存文件的路径
            String filepath = destDir + File.separator + createNewDir();
            File destfile = new File(uploadPath + filepath);
            if (!destfile.exists()) {
                destfile.mkdirs();
            }
            //文件新名称
            String fileNameNew = getFileNameNew() + "." + suffix;
            File f = new File(destfile.getAbsoluteFile() + File.separator + fileNameNew);
            if (f.exists()) {
                return filepath + File.separator + fileNameNew;
            }
            file.transferTo(f);
            f.createNewFile();
            return filepath + File.separator + fileNameNew;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 为文件重新命名,命名规则为当前系统时间毫秒数
     *
     * @return string
     */
    private static String getFileNameNew() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return fmt.format(new Date());
    }

    /*
    *以当前日期为名,创建新文件夹
    @return
    */
    private static String createNewDir() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        return fmt.format(new Date());
    }
}

WebUploadResult.java类:

/**
 * 默认的页面请求返回的model对象.用来包裹controller的页面输出
 */
public class WebUploadResult {
    private int status;
    private String filePath;
    private WebUploadError error;
    private String id;
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public String getFilePath() {
        return filePath;
    }
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
    public WebUploadError getError() {
        return error;
    }
    public void setError(WebUploadError error) {
        this.error = error;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
}

WebUploadError.java类:

/**
 * 默认的页面请求返回的model对象.用来包裹controller的页面输出
 */
public class WebUploadError {
   private int code;
   private String message;
   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;
   }
}

注意:

在普通文件上传中,我们都是用:

<input type="file" name="file">

这样来控制上传的。

在LayUI上传组件中,实际上也是用这种方式来实现的:

<input class="layui-upload-file" type="file" name="file">

ajax取消异步请求

$.ajax({
    url: '/user/login',
    data: {},
    dataType: 'json',
    type: 'post',
    async: false,//取消异步请求
    success: function(result){
        
    } 
})
0

评论区