本篇文章主要记录本人学习过程中的一些小干货。
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){
}
})
评论区