学习笔记(杂用)(一)

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

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

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

后台控制器中代码:

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

前端页面中代码:

1
2
3
4
5
6
7
8
9
10
<!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请求中文乱码的方法网上很常见,一搜一大堆,大概就是以下三步骤:

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

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

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

访问地址:Springboot官方文档

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

1
2
3
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中加入依赖)

1
2
3
4
5
6
7
<!--SpringBoot热部署配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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

1
2
#配置项目热部署
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下添加

1
2
#表明静态资源的位置,默认值是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:

1
npm install jquery --save

安装Bootstrap:

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

在main.js中加入:

1
2
3
4
5
6
/*引入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

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

设置自定义favicon

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

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

添加无效解决

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

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

其他页面模板可以使用:

1
2
3
4
5
6
<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常用的日期分组统计方法:

按月统计(一)

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

按天统计(二)

1
2
3
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时间戳格式

1
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时间格式

1
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)错误解决方法

1
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语句为:

1
select version(), @@sql_mode;

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

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

jQuery表格排序插件

引用文件

–js:

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

–css

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

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<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格式化日期格式

1
<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获取项目根路径

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

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

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

1
2
3
4
5
6
7
8
<!--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>

例如写个注册功能:

1
2
3
4
5
6
7
8
9
10
<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>

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

1
2
3
4
5
6
7
8
9
10
<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>

表单验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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 函数名()

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

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

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

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

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

在ShiroConfig中添加:

1
2
3
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上加上主键生成策略:

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

layui弹窗倒计时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//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分页的相关方法

1
2
3
4
5
6
7
8
9
10
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添加点击事件

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

springboot集成swagger2

加入依赖:

1
2
3
4
5
6
7
8
9
10
11
<!--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配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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配置:

1
2
#swagger2配置
swagger.enabled=true

shiro放行swagger2访问页面:

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

layui表格日期格式化

1
{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

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

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

页面的表格区域:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//执行一个 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@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

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

layui日期时间选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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语句

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

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

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

1
&useUnicode=true&characterEncoding=UTF-8

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

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

layui表格添加数据自动刷新

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

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

pom文件加依赖:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.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});
}
}
})

后台代码(举例):

1
2
3
4
5
6
7
8
9
10
/*批量删除基金信息*/
@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目录中的静态样式

1
2
3
4
5
6
7
<!--第一种方式,使用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文件导入依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!--通过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>

具体实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
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);
}
}
}

返回数据格式:

1
2
3
4
5
6
7
8
9
10
11
12
{
"name":"李晶",
"idNo":"320723199702255613",
"respMessage":"身份证信息匹配",
"respCode":"0000",
"province":"江苏省",
"city":"连云港市",
"county":"灌云县",
"birthday":"19970225",
"sex":"M",
"age":"23"
}

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

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

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

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

2、导入上传组件jar包

1
commons-fileupload、commons-io

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

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 设置上传文件最大值   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、前端页面代码

1
2
3
4
5
6
7
<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代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<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代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 文件上传
* @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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 默认的页面请求返回的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类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 默认的页面请求返回的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;
}
}

注意:

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

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

这样来控制上传的。

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

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

ajax取消异步请求

1
2
3
4
5
6
7
8
9
10
$.ajax({
url: '/user/login',
data: {},
dataType: 'json',
type: 'post',
async: false,//取消异步请求
success: function(result){

}
})
点击查看

本文标题:学习笔记(杂用)(一)

文章作者:LiJing

发布时间:2021年01月27日 - 16:50:06

最后更新:2023年06月03日 - 10:00:10

原始链接:https://blog-next.xiaojingge.com/posts/3902366258.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------------本文结束 感谢您的阅读-------------------