接收Http请求的几种方式

最近在开发过程中,遇到了我们公司的几个老项目,采用的是传统单体项目,这种项目之间需要交互,项目A请求项目B,B将结果回调给A,我们采用了Http Post请求的方式,在接收Http请求的时候,遇到了不少问题,所以总结一下接收Http Post请求的几种方式。

1.@RequestBody注解直接接收

请求类型必须是:application/json

	/**
     * 主动请求方-A
     */
    @PostMapping("request-callback")
    public static void requestCallback() {
     

        TreeMap<String, String> map = new TreeMap<>();
        map.put("name", "六六");
        map.put("age", "2");
        map.put("version", "1.0");

        String response;
        try {
     
            response = RequestUtil.post("http://127.0.0.1:8080/callback/response-callback", map);
        } catch (Exception e) {
     
            throw new RuntimeException("请求异常!");
        }
        LOGGER.info("回调返回 response = :{}", response);
    }
    // 项目A日志结果:回调返回 response = :回调成功!

    /**
     * 接收请求方-B-1
     */
    @PostMapping("response-callback")
    public String responseCallback(@RequestBody CallbackDTO callbackDTO) {
     

        if (callbackDTO != null) {
     
            LOGGER.info("dto:{}", JSON.toJSONString(callbackDTO));
            return "回调成功!";
        }
        return "回调失败!";
    }
    // 项目B日志结果:dto:{"age":2,"name":"六六","version":"1.0"}

2.WebUtils.getParametersStartingWith(request, “”) 表单方式接收

  • 熟悉JavaWeb开发的同学应该都知道request中有一个方法叫做request.getParameterMap() ,返回一个Map;

比如,前端提交一个表单:

<input type="text" name="p_name" value="六六">
<input type="text" name="p_age" value="2">
<input type="text" name="f_sex" value="女">

request.getParameterMap()会得到一个Map:

{
     p_name=六六, p_age=2, f_sex=}

但是我们后端可能只需要带"p_"这个前缀的字段,这时我们就可以用WebUtils.getParametersStartingWith(request, “p_”)这个方法去指定获取带"p_"前缀的字段,返回值也是一个Map。它会去掉前缀并且将不是"p_"前缀的字段过滤掉:

{
     name=六六, age=2}

也可以不传参,WebUtils.getParametersStartingWith(request, “”),他获取的结果和request.getParameterMap()一样:

{
     p_name=六六, p_age=2, f_sex=}
  • 同样的,如果请求类型是 “Content-Type”,“application/x-www-form-urlencoded” 时,也可以使用这个方法去接收;
	/**
     * 主动请求方-A
     */
    @PostMapping("request-callback")
    public static void requestCallback() {
     

        TreeMap<String, String> map = new TreeMap<>();
        map.put("p_name", "六六");
        map.put("p_age", "2");
        map.put("f_version", "1.0");

        String response;
        try {
     
            response = RequestUtil.post("http://127.0.0.1:8080/callback/response-callback", map);
        } catch (Exception e) {
     
            throw new RuntimeException("请求异常!");
        }
        LOGGER.info("回调返回 response = :{}", response);
    }
	// 项目A日志结果:回调返回 response = :回调成功!

    /**
     * 接收请求方-B-2
     */
    @PostMapping("response-callback")
    public String responseCallback() {
     

        Map<String, Object> params = WebUtils.getParametersStartingWith(request, "p_");

        LOGGER.info("params :{}", JSON.toJSONString(params));

        return "回调成功!";
    }
    // 项目B日志结果:params :{"age":"2","name":"六六"}

和我们预想的一样,项目B接收到了请求,获取到了"p_"前缀的参数,将前缀自动去掉,并且给了项目B回调结果。

3.request.getReader()的方式接收

	/**
     * 主动请求方-A
     */
    @PostMapping("request-callback")
    public static void requestCallback() {
     

        TreeMap<String, String> map = new TreeMap<>();
        map.put("name", "六六");
        map.put("age", "2");
        map.put("version", "1.0");

        String response;
        try {
     
            response = RequestUtil.post("http://127.0.0.1:8080/callback/response-callback", map);
        } catch (Exception e) {
     
            throw new RuntimeException("请求异常!");
        }
        LOGGER.info("回调返回 response = :{}", response);
    }
    // 项目A日志结果:回调返回 response = :回调成功!
    
	/**
     * 接收请求方-B-3
     */
    @PostMapping("response-callback")
    public String responseCallback() {
     

        String content;
        try {
     
            StringBuilder sb = new StringBuilder();
            String line;
            while (!StringUtils.isBlank((line = request.getReader().readLine()))) {
     
                sb.append(line);
            }
            content = sb.toString();
            LOGGER.info("content = {}", content);

        } catch (Exception e) {
     
            LOGGER.error("msg={},stack={}", e.getMessage(), ExceptionUtils.getStackTrace(e));
        }
        return "回调成功!";
    }
    // 项目B日志结果:content = {"age":"2","name":"六六","version":"1.0"}

使用request.getInputStream()返回请求内容字节流一样可以获取。

4.工具类

我使用的Http请求工具类有两个,一个是hutool工具类,一个自己封装的。

<!--hutool工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>4.1.8</version>
</dependency>
/**
 * fshows.com
 * Copyright (C) 2013-2019 All Rights Reserved.
 */
package com.example.callbackdemo.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

/**
 * post请求工具类
 * @author liuyuan
 */
@Slf4j
public class RequestUtils {
     
    /**
     * 超时时间10秒
     */
    private static final int TIMEOUT = 10000;

    public static String post(String url, Object object) {
     
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(TIMEOUT).setConnectTimeout(TIMEOUT).build();
        String content = null;
        HttpPost post = new HttpPost(url);
        post.addHeader("Content-Type", "application/json");
        post.setConfig(requestConfig);
        String body = JSON.toJSONString(object, SerializerFeature.WriteNullStringAsEmpty);
        log.info("执行POST请求 body={}", body);
        post.setEntity(new StringEntity(body, "UTF-8"));
        try {
     
            CloseableHttpClient client = HttpClientBuilder.create().build();
            CloseableHttpResponse closeableHttpResponse = client.execute(post);
            content = EntityUtils.toString(closeableHttpResponse.getEntity(), "UTF-8");
        } catch (IOException e) {
     
            log.warn("执行POST请求异常params={},e={}", JSON.toJSONString(object), ExceptionUtils.getStackTrace(e));
        } finally {
     
            post.releaseConnection();
        }
        return content;
    }
}

5.总结

request.getParameter()、request.getInputStream()、request.getReader()和@RequestBody注解是互斥的,只能调用其中一个,如果想要同时使用,需要做特殊处理。

你可能感兴趣的:(Post请求,Http请求)