RestTemplate用法及封装

RestTemplate是什么

  • 传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient。不过此种方法使用起来太过繁琐。spring提供了一种简单便捷的模板类来进行操作,这就是RestTemplate。

封装使用


import com.example.demo.controllers.IndexController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
 * http请求公共类
 */
public class ResponseResule {

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    /**
     * 请求接口公共方法
     * @param Methods
     * @param url
     * @param UrlParams
     * @return
     */
    public static String getResponse(String url, HttpMethod Methods, Map<String, String> UrlParams, Map<String, String> HeaderParams) throws IOException {
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = Methods;
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 设置用户提交的header头数据
        if (!HeaderParams.isEmpty()) {
            HeaderParams.forEach((k, v) -> {
                headers.set(k, v);
            });
        }
        // 将请求头部和参数合成一个请求
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        if (Methods == HttpMethod.GET) {
            String _UrlParams = getUrlParamsByMap(UrlParams);
            url = url + "?" +_UrlParams;
        }else {
            if (!UrlParams.isEmpty()) {
                UrlParams.forEach((k,v) ->{
                    params.put(k, Collections.singletonList(v));
                });
            }
        }
//        logger.info("URL:{}", url);
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        // 执行HTTP请求,将返回的结构使用spring ResponseEntity处理http响应
        ResponseEntity<byte[]> responseEntity = client.exchange(url, method, requestEntity, byte[].class);
        String contentEncoding = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING);
        // gzip编码
        if ("gzip".equals(contentEncoding)) {
            // gzip解压服务器的响应体
            byte[] data = unGZip(new ByteArrayInputStream(responseEntity.getBody()));
//            logger.info(new String(data, StandardCharsets.UTF_8));
            return new String(data);
        } else {
            // 其他编码暂时不做处理(如果需要处理其他编码请自行扩展)
            return new String(responseEntity.getBody());
        }
    }

    /**
     * Gzip解压缩
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] unGZip(InputStream inputStream) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream)) {
            byte[] buf = new byte[4096];
            int len = -1;
            while ((len = gzipInputStream.read(buf, 0, buf.length)) != -1) {
                byteArrayOutputStream.write(buf, 0, len);
            }
            return byteArrayOutputStream.toByteArray();
        } finally {
            byteArrayOutputStream.close();
        }
    }

    /**
   * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
   * @param params 需要排序并参与字符拼接的参数组
   * @return 拼接后字符串
   * @throws UnsupportedEncodingException
   */
    public static String getUrlParamsByMap(Map<String, String> params) throws UnsupportedEncodingException {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            value = URLEncoder.encode(value, "UTF-8");
            if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }
}

使用方法

String url = "http://192.168.1.115:8621/test";
// 设置参数
String username = "admin";
Map<String, String> params = new HashMap<>();
params.put("username", username);
// 设置Header头数据
Map<String, String> HeaderParams = new HashMap<>();
// HttpMethod.POST / HttpMethod.GET
String result  = ResponseResule.getResponse(url, HttpMethod.POST, params, HeaderParams); 
System.out.println(result); // 返回json字符串数据

mac系统默认使用高版本jdk导致burpsuite无法启动

1、之前在mac中装了jdk11 之后发现burp suite无法启动,原因是双击jar启动的时候,系统默认指定的jdk版本是根据/usr/libexec/java_home得到的,而网上的修改jdk版本的教程都是修改当前命令行的环境变量,不会影响系统

解决方法是进入/Library/Java/JavaVirtualMachines/ 目录,打开除了jdk1.8之外的其他jdk目录下面的Contents目录,编辑Info.plist

在jvmvserion下面的版本号前面加一个!
60a363a3b682a21abc000000.jpg

60a363acb682a21abc000001.jpg

一、java SSM 框架搭建(maven)

一、SSM简介

SSM框架是spring MVC,spring和mabatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层。

spring MVC  :负责请求的转发和视图管理。

spring      :实现业务对象管理。

mybatis     :作为数据对象的持久化引擎。

二、安装maven构建工具(Mac && Linux平台)

1、进入maven官网下载maven免编译包(https://maven.apache.org/download.cgi)

apache-maven-3.6.2-bin.tar.gz

2、解压tar包并将其放到自己指定的位置中

3、进入maven项目目录中编辑conf/settings.xml文件

4、找到 localRepository 标签将其修改为本机下的任意指定目录(<localRepository>/Users/test/Applications/webapplib</localRepository>)

5、找到<mirror>标签,将原有的标签注释,修改成阿里云的下载镜像
    <mirror>
        <id>alimaven</id>
        <mirrorOf>central</mirrorOf>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>
6、保存conf/settings.xml文件,到此maven就配置完成了

三、利用maven创建webapp项目

1、打开IntelliJ IDEA 编辑器,选择[Create New Project] 新建项目
maven_2.png

2、输入自己项目包名和项目名称
maven_3.png

3、修改默认的maven配置文件,选择自己安装的那个maven配置文件
maven_4.png

4、直接点击Finish
maven_5.png

6、点击完成后进入到编辑器配置pom.xml,添加自己需要的依赖包
maven_6.png

7、配置项目的源码目录和资源目录
maven_6.1.png

8、添加一个项目编译和打包目录
maven_7.png

9、添加tomcat服务配置(先下载tomcat, 然后在tomcat配置页面选择Application server修改tomcat服务器路径)
maven_8.png

10、配置tomcat服务端口
maven_9.png

11、选择之前添加好的项目编译和打包目录(注意Deployment选项下的Application context,将值修改为 / )
maven_10.png

12、选择热编启动选项(这个可以不修改,使用默认即可)
maven_11.png

13、运行项目后在浏览器输入http://localhost:[port]即可看到 hello world
maven_12.png

Linux计划任务命令crontab配置详解

1、任务命令配置说明

# .---------------- 分钟 (0 - 59)
# | .-------------- 小时 (0 - 23)
# | | .------------ 天 (1 - 31)
# | | | .---------- 月 (1 - 12) OR jan,feb,mar,apr ...
# | | | | .-------- 一周中的某一天(0-6)(星期日=0或7)或周日、周一、周二、周三、周四、周五、周六
# | | | | |
# * * * * * user-name command to be executed

2、任务命令例子-1

*/10 * * * * /usr/local/php/bin/php /usr/local/apache2/htdocs/oneindex/one.php cache:refresh  这个是每十分钟执行一次

3、任务命令例子-2

0 * * * * /usr/local/php/bin/php /usr/local/apache2/htdocs/oneindex/one.php token:refresh     每小时执行一次

4、编辑计划任务相关命令

crontab -l 输出当前的crontab任务命令列表。 
crontab -r 删除当前的crontab任务命令文件。 
crontab -e 使用VISUAL或者EDITOR环境变量所指的编辑器编辑当前的crontab文件。当结束编辑离开时,编辑后的文件将自动安装。 

laravel-5.6 【mews/captcha】图片验证码 api接口形式获取、验证,不通过session

[mews/captcha]

扩展GitHub地址: https://github.com/mewebstudio/captcha

前期准备与说明

在laravel 中使用此扩展,正常的用法是通过session来保存与验证用户输入的验证码是否正确,但我目前的项目是前后台彻底分离的。前台使用vue框架来搭建,后台用laravel来做api后台的接口。前后台通过jwt来标识用户。所以没法使用session来使用这个扩展,百度了好久,无用,最终还是在官方论坛找到解决方案,在此贴出方案,以便后来人查阅

  1. 在laravel中引入此扩展【我的框架版本laravel5.5】

    composer require mews/captcha
    
  1. 找到config/app.php下的providers,添加如下代码

    \Mews\Captcha\CaptchaServiceProvider::class,
    
  2. 找到config/app.php下的aliases,添加如下代码

    'Captcha' => Mews\Captcha\Facades\Captcha::class,
    
  3. 发布配置文件

    php artisan vendor:publish
    

    之后便可以在 config/captcha.php下,配置验证码

   return [
    'characters' => '2346789abcdefghjmnpqrtuxyzABCDEFGHJMNPQRTUXYZ',

    'default'   => [
        'length'    => 9,
        'width'     => 120,
        'height'    => 36,
        'quality'   => 90,
        'math'      => true,
    ],

    'flat'   => [
        'length'    => 6,
        'width'     => 160,
        'height'    => 46,
        'quality'   => 90,
        'lines'     => 6,
        'bgImage'   => false,
        'bgColor'   => '#ecf2f4',
        'fontColors'=> ['#2c3e50', '#c0392b', '#16a085', '#c0392b', '#8e44ad', '#303f9f',     '#f57c00', '#795548'],
        'contrast'  => -5,
    ],

    'mini'   => [
        'length'    => 3,
        'width'     => 60,
        'height'    => 32,
    ],

    'inverse'   => [
        'length'    => 5,
        'width'     => 120,
        'height'    => 36,
        'quality'   => 90,
        'sensitive' => true,
        'angle'     => 12,
        'sharpen'   => 10,
        'blur'      => 2,
        'invert'    => true,
        'contrast'  => -5,
    ]

];

正文开始

因为正常用session的使用方案比较简单,在此不赘述。
下面放上通过api来验证的前后端的关键代码

  1. PHP返回验证码

    // 路由
    Route::get('GetCaptchaImg','UserController@GetCaptchaImg')->name("GetCaptchaImg");
    // 代码
    public function GetCaptchaImg(Request $request){
        return app('captcha')->create('inverse', true);
    }
    
    说明:这里返回的url.img是base64后的图片,可直接放入img标签中的src属性中。key值是与图片绑定的数值,之后需传给后台验证。
    
  2. PHP关键验证代码

    // 路由
    Route::post('CheckCaptcha','UserController@CheckCaptcha')->name("CheckCaptcha");
    // 代码
    public function CheckCaptcha(Request $request){
        $key = $this->FormCheck->isEmpty($request->key,'验证码key');
        if (!$key->code) {
            return result($key->msg);
        }
        $captcha = $this->FormCheck->isEmpty($request->captcha,'验证码');
        if (!$captcha->code) {
            return result($captcha->msg);
        }
    
        if (!captcha_api_check($request->captcha, $request->key)){
            return $this->Resources('验证失败', 0, []);
        }
        return $this->Resources('验证成功', 1, []);
    }
    
  3. 验证结果
    验证码2.png
    验证码.png