4
2
0
2

记录

记录

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  网段名称

image

2. 创建docker服务时,指定创建的新网段即可

docker-compose 构建时

image

普通镜像构建时

docker run -itd --net=test-network --name nginx5 nginx

9、Nginx解决 413 Request Entity Too Large(请求实体太大)

之前在做上传功能的时候,出现了 413 Request Entity Too large ,百度了一下解决方案,最终解决了,做一下记录

image

在请求体的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与域名进行绑定

image

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进行设置,自动就设置好了

image

3. 安装包安装

  • windows 下载地址https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
  • 根据自己的系统下载对应的 jdk,文件结尾要是 tar.gz

image

  • 把下载的 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}
  1. ssl放域名对应证书
  2. config放nginx配置文件
  3. 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 文件夹中

image

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>
posted @ 2021-11-18 16:29  CoderTL  阅读(130)  评论(0编辑  收藏  举报