记录
记录
1、docker 安装 redis
1.1 首先在 opt
下创建 redis
目录,用于存放redis的数据和配置文件
mkdir /opt/redis
cd /opt/redis
1.2 创建redis的配置文件,并写入配置
vim redis.conf
# 是否持久化
appendonly yes
# 设置密码
requirepass admin
1.3 拉取镜像,默认是最新版
docker pull redis
1.4 启动Redis容器,指定使用的配置文件 redis-server /etc/redis/reids.conf
,默认是不使用配置文件
docker run -p 6379:6379 -d --name redis-6379 -v /opt/redis/data:/data -v /opt/redis/redis.conf:/etc/redis/redis.conf redis redis-server /etc/redis/redis.conf
2、base64编码 出现\r\n 换行符
2.1 概述
Base64是一种字符串编码格式,Base64采用A-Z a-z 0-9 “+“ “/“这一共64个字符来编码原始字符(还有垫字符“=“)。一个字符本身是1个字节,也就是8位,而Base64编码后的一个字符只能表示能表示6位的信息。也就是原始字符串中3字节的信息编码会变成4字节的信息。Base64的主要作用是满足MIME传输需求,在传输过程中都是用ASCII支持的可见字符。Base64是基于字节的编码,所以不同字符集下的相同字符在Base64下可能有着不同编码
2.2 问题描述
将编码后的字符串输出后发现字符串中存在换行符
2.3 问题分析
根据RFC822规定,BASE64Encoder编码每76个字符,还需要加上一个回车换行,部分Base64编码的java库还按照这个标准实行
2.4 解决
2.4.1 导入jar包
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
2.4.2 编写代码
Base64.encodeBase64String(byte[] binaryData);
3、中文转unicode编码
javascript脚本
// 转为unicode 编码
function encodeUnicode(str) {
var res = [];
for ( var i=0; i<str.length; i++ ) {
res[i] = ( "00" + str.charCodeAt(i).toString(16) ).slice(-4);
}
return "\\u" + res.join("\\u");
}
4、Windows彻底停止 nginx服务
taskkill /f /t /im nginx.exe
5、Linux清除无用的 docker volume内存占用
# 列出
docker volume ls -qf dangling=true
# 删除
docker volume rm $(docker volume ls -qf dangling=true)
# 查看
docker system df
6、linux后台运行jar包,控制台打印进行 utf-8编码
nohup命令:英文全称 no hang up(不挂起),用于不挂断地运行指定命令,退出终端不会影响程序的运行
语法格式: nohup Command Arg …
参数说明:
Command:要执行的命令
Arg:一些参数,可以指定输出文件
&:让命令在后台运行
举例:
nohup java -jar boot工程.jar &> hello.log &
上述指令的含义为: 后台运行 java -jar 命令,并将日志输出到hello.log文件
那么经过上面的介绍,我们可以推测中,我们要想让当前部署的项目后台运行,就可以使用下面的指令:
nohup java -jar helloworld.jar &> hello.log &
这样的话,我们的项目就已经启动成功了,我们可以通过ps指令,查看到系统的进程。
7、
8、docker网段冲突问题
之前在公司环境centos7服务器上安装docker,然后部署项目后,发现无法访问,xhsell也无法连接需要经过vpn才能连接上去。(需要和服务器同网段,才能连接)
经过排查,原来公司当前是B类网络,本机ip为 172.16.x.x ,安装docker后创建了虚拟网络网桥,恰好也是B类网段,172.16.1.0/16。原因就在本机xshell连接服务器的时候,直接找到了 172.16.1.0,从而导致无法通过xshell 连接目标服务器。
1. 解决办法
修改docker网段, 避开本地所有网段即可。
局域网保留地址:
A类 | 10.0.0.0/8 |
---|---|
B类 | 172.16.0.0/16 |
C类 | 192.168.0.0/24 |
创建 docker 网络
# --driver 网络模式 --subnet 网段
docker network create --driver=bridge --subnet 192.168.0.1/24 网段名称
2. 创建docker服务时,指定创建的新网段即可
docker-compose 构建时
普通镜像构建时
docker run -itd --net=test-network --name nginx5 nginx
9、Nginx解决 413 Request Entity Too Large(请求实体太大)
之前在做上传功能的时候,出现了 413 Request Entity Too large ,百度了一下解决方案,最终解决了,做一下记录
在请求体的body中,Content-Length的大小大于Nginx默认的 request body后,会抛出这个错误
Nginx默认 Request body大小为 1M
1.解决方案
1. 打开Nginx的配置文件 nginx.conf
2. 在 http {}中,加入客户端最大请求体大小设置
3. client_max_body_size 10m;
4. 重启Nginx
10、SpringSecurity自定义用户密码验证
我的用户密码前台输入后,需要和用户名关联进行加密比较,所以重写了AuthenticationProvider的实现类进行处理;
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
@Autowired
private ISysUserService iSysUserService;
@Autowired
private PasswordEncorder passwordEncorder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String presentedPassword = (String)authentication.getCredentials();
UserDetails userDeatils = null; // 根据用户名获取用户信息
SysUser sysUser = this.iSysUserService.getUserByName(username);
if (StringUtils.isEmpty(sysUser)) {
throw new BadCredentialsException("用户名不存在");
} else {
userDeatils = new User(username, sysUser.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList("USER")); // 自定义的加密规则,用户名、输的密码和数据库保存的盐值进行加密
String encodedPassword = PasswordUtil.encrypt(username, presentedPassword, sysUser.getSalt());
if (authentication.getCredentials() == null) {
throw new BadCredentialsException("登录名或密码错误");
} else if (!this.passwordEncorder.matches(encodedPassword, userDeatils.getPassword())) {
throw new BadCredentialsException("登录名或密码错误");
} else {
UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(userDeatils, authentication.getCredentials(), userDeatils.getAuthorities());
result.setDetails(authentication.getDetails());
return result;
}
}
}
@Override
public boolean supports(Class<?> authentication) {
return true;
}
}
然后在SecurityConfiguration配置中启用
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(this.myAuthenticationProvider);
}
11、内网ip绑定域名
1.修改 hosts 文件
vi /etc/hosts
2.将ip与域名进行绑定
3. 使 hosts 文件生效
/etc/init.d/dns-clean start
/etc/init.d/networking restart
12、Centos 7安装JDK1.8
本人根据网络上的安装资料,实际操作成功,做一下记录
1. 检查系统是否有自带的 open-Jdk
rpm -qa |grep java
rpm -qa |grep jdk
rpm -qa |grep gcj
如果安装可以使用rpm -qa | grep java | xargs rpm -e --nodeps 批量卸载所有带有Java的文件 这句命令的关键字是java
2. yum安装
2.1 检索 java 列表(openJDK1.8)
yum list java*
yum list java-1.8*
2.2 安装1.8.0的所有文件
yum install java-1.8.0-openjdk* -y
这样安装有一个好处就是不需要对path进行设置,自动就设置好了
3. 安装包安装
- windows 下载地址https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- 根据自己的系统下载对应的 jdk,文件结尾要是 tar.gz
- 把下载的 jdk 复制到 Centos7 指定目录下(/usr/local)
- 解压压缩包
tar -zxvf 安装包
- 配置JDK环境变量
#java environment
export JAVA_HOME=/usr/jdk1.8.0_321
export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
export PATH=$PATH:${JAVA_HOME}/bin
键入命令source /etc/profile 使配置文件生效
检查
java -version
13、SpringBoot访问外部接口总结
访问外部接口, 为网络资料整理
方案一:原生Http请求
@RequestMapping("/doPostGetJson")
public String doPostGetJson() throws ParseException {
//此处将要发送的数据转换为json格式字符串
String jsonText = "{id:1}";
JSONObject json = (JSONObject) JSONObject.parse(jsonText);
JSONObject sr = this.doPost(json);
System.out.println("返回参数:" + sr);
return sr.toString();
}
public static JSONObject doPost(JSONObject date) {
HttpClient client = HttpClients.createDefault();
// 要调用的接口方法
String url = "http://192.168.1.101:8080/getJson";
HttpPost post = new HttpPost(url);
JSONObject jsonObject = null;
try {
StringEntity s = new StringEntity(date.toString());
s.setContentEncoding("UTF-8");
s.setContentType("application/json");
post.setEntity(s);
post.addHeader("content-type", "text/xml");
HttpResponse res = client.execute(post);
String response1 = EntityUtils.toString(res.getEntity());
System.out.println(response1);
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String result = EntityUtils.toString(res.getEntity());// 返回json格式:
jsonObject = JSONObject.parseObject(result);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return jsonObject;
}
方案二: 采用 Feign 进行消费
1、在maven项目中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
2、编写接口,放置在service层
这里的decisionEngine.url 是配置在properties中的 是ip地址和端口号
decisionEngine.url=http://192.168.101.10:9999/decision/person 是接口名字
@FeignClient(url = "${decisionEngine.url}",name="engine")
public interface DecisionEngineService {
@RequestMapping(value="/decision/person",method= RequestMethod.POST)
public JSONObject getEngineMesasge(@RequestParam("uid") String uid,@RequestParam("productCode") String productCode);
}
3、在Java的启动类上加上@EnableFeignClients
@EnableFeignClients //参见此处
@EnableDiscoveryClient
@SpringBootApplication
@EnableResourceServer
public class Application implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
@Autowired
private AppMetricsExporter appMetricsExporter;
@Autowired
private AddMonitorUnitService addMonitorUnitService;
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
4、在代码中调用接口即可
@Autowired
private DecisionEngineService decisionEngineService ;
// ...
decisionEngineService.getEngineMesasge("uid" , "productCode");
方案三: 采用 RestTemplate方法
在Spring-Boot开发中,RestTemplate同样提供了对外访问的接口API,这里主要介绍Get和Post方法的使用。Get请求提供了两种方式的接口getForObject 和 getForEntity,getForEntity提供如下三种方法的实现。
3.1 Get请求之——getForEntity(Stringurl,Class responseType,Object…urlVariables)
该方法提供了三个参数,其中url为请求的地址,responseType为请求响应body的包装类型,urlVariables为url中的参数绑定,该方法的参考调用如下:
// http://USER-SERVICE/user?name={name)
RestTemplate restTemplate=new RestTemplate();
Map<String,String> params=new HashMap<>();
params.put("name","dada"); //
ResponseEntity<String> responseEntity=restTemplate.getForEntity("http://USERSERVICE/user?name={name}",String.class,params);
3.2 Get请求之——getForEntity(URI url,Class responseType)
该方法使用URI对象来替代之前的url和urlVariables参数来指定访问地址和参数绑定。URI是JDK java.net包下的一个类,表示一个统一资源标识符(Uniform Resource Identifier)引用。参考如下:
RestTemplate restTemplate=new RestTemplate();
UriComponents uriComponents=UriComponentsBuilder.fromUriString("http://USER-SERVICE/user?name={name}")
.build()
.expand("dodo")
.encode();
URI uri=uriComponents.toUri();
ResponseEntity<String> responseEntity=restTemplate.getForEntity(uri,String.class).getBody();
3.3 Get请求之——getForObject
getForObject方法可以理解为对getForEntity的进一步封装,它通过HttpMessageConverterExtractor对HTTP的请求响应体body内容进行对象转换,实现请求直接返回包装好的对象内容。getForObject方法有如下:
getForObject(String url,Class responseType,Object...urlVariables)
getForObject(String url,Class responseType,Map urlVariables)
getForObject(URI url,Class responseType)
3.4 Post 请求
Post请求提供有三种方法,postForEntity、postForObject和postForLocation。其中每种方法都存在三种方法,postForEntity方法使用如下:
RestTemplate restTemplate=new RestTemplate();
User user=newUser("didi",30);
ResponseEntity<String> responseEntity=restTemplate.postForEntity("http://USER-SERVICE/user",user,String.class); //提交的body内容为user对象,请求的返回的body类型为String
String body=responseEntity.getBody();
postForEntity存在如下三种方法的重载
postForEntity(String url,Object request,Class responseType,Object... uriVariables)
postForEntity(String url,Object request,Class responseType,Map uriVariables)
postForEntity(URI url,Object request,Class responseType)
postForEntity中的其它参数和getForEntity的参数大体相同
14、Docker安装Nginx(附带域名SSL证书)
方案为网络资源,记录一下
1、直接安装最新的nginx
docker pull nginx
2、由于后期需要方便配置与管理nginx,需要把nginx容器内的文件夹进行挂载到宿主机中,所以此处需要进行到自己心仪的盘中创建文件夹(本次说明在/home)
mkdir nginx && cd $_ && mkdir -p {ssl,config,logs}
- ssl放域名对应证书
- config放nginx配置文件
- logs放nginx日志
3、先启动一个nginx容器用于cp对应的文件夹类型,用于后期挂载使用
docker run --name nginx -p 80:80 -d nginx
4、进行容器文件cp
docker cp nginx:/etc/nginx/nginx.conf /home/nginx/config/
docker cp nginx:/etc/nginx/conf.d /home/nginx
docker cp nginx:/usr/share/nginx/html /home/nginx
5、此时需要停止并删除已启动容器
docker stop nginx
docker rm nginx
6、把我们域名对应的证书放置 SSL
文件夹中
7、现在开始配置一下我们的nginx.conf文件了(注意:本例子80端口强制跳转到443,即强https)
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
client_max_body_size 100m;
include mime.types;
server {
listen 80;
server_name www.xxx.com;
rewrite ^(.*) https://$server_name$1 permanent;
}
server {
listen 443 ssl; # 1.1版本后这样写
server_name www.xxx.com; #填写绑定证书的域名
ssl_certificate /home/xxx.com.pem; # 指定证书的位置,绝对路径
ssl_certificate_key /home/xxx.com.key; # 绝对路径,同上
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:1m;
fastcgi_param HTTPS on;
fastcgi_param HTTP_SCHEME https;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
}
# 引入扩展配置(可以细分服务nginx)
include /etc/nginx/conf.d/*.conf;
}
8、此时可以输入命令进行启动容器
docker run --name nginx -p 443:443 -p 80:80 -v /home/nginx/html:/usr/share/nginx/html -v /home/nginx/config/nginx.conf:/etc/nginx/nginx.conf/ -v /home/nginx/logs:/var/log/nginx/ -v /home/nginx/ssl:/etc/nginx/ssl/ --privileged=true -d --restart=always nginx
9、此时启动成功完毕
10、浏览器输入对应域名或者ip即可访问
需要在服务器安全组中开放80和443端口,如果服务器内部也启用了防护墙,也需要进行开放,但docker会根据-p 端口进行代理开放
15、查询时间范围内的数据,默认不存在月数据给0
@Override
public JsonResult<List<XscafxQueryResult>> queryXscafx(SytjQueryParam queryParam) {
queryParam.setKssj(DateUtil.beginOfDay(queryParam.getKssj()));
queryParam.setJssj(DateUtil.endOfDay(queryParam.getJssj()));
List<XscafxQueryResult> xscafxQueryResultList = xssjsrMapper.queryXscafx(queryParam);
// 获取起始日期的月份
int startYear = DateUtil.year(queryParam.getKssj());
int startMonth = DateUtil.month(queryParam.getKssj()) + 1; // 月份从0开始,需要加1
// 获取结束日期的月份
int endYear = DateUtil.year(queryParam.getJssj());
int endMonth = DateUtil.month(queryParam.getJssj()) + 1; // 月份从0开始,需要加1
// 构造月份数组
String[] months = new String[(endYear - startYear) * 12 + (endMonth - startMonth) + 1];
int index = 0;
for (int year = startYear; year <= endYear; year++) {
int monthStart = (year == startYear) ? startMonth : 1;
int monthEnd = (year == endYear) ? endMonth : 12;
for (int month = monthStart; month <= monthEnd; month++) {
months[index++] = String.format("%04d-%02d", year, month);
}
}
List<XscafxQueryResult> queryResultList = new ArrayList<>();
Arrays.asList(months).forEach(month -> {
XscafxQueryResult queryResult = new XscafxQueryResult();
queryResult.setYf(month);
queryResult.setAjs(0L);
for (XscafxQueryResult xscafxQueryResult : xscafxQueryResultList) {
if (month.equals(xscafxQueryResult.getYf())) {
queryResult.setAjs(xscafxQueryResult.getAjs());
}
}
queryResultList.add(queryResult);
});
return new JsonResult<>(queryResultList);
}
16、模糊查询sql拼接
<if test="almc != null and almc != ''">
AND almc LIKE CONCAT('%', #{almc}, '%')
</if>
本文来自博客园,作者:CoderTL,转载请注明原文链接:https://www.cnblogs.com/codertl/p/15573023.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix