Spring使用RestTemplate调用Flask接口API

一、 什么是RestTemplate?

RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。

调用 RestTemplate 的默认构造函数,RestTemplate 对象在底层通过使用java.net包下的实现创建 HTTP 请求,可以通过使用 ClientHttpRequestFactory 指定不同的HTTP请求方式。
ClientHttpRequestFactory 接口主要提供了两种实现方式

  1. 一种是 SimpleClientHttpRequestFactory,使用 J2SE 提供的方式(即java.net 包提供的方式)创建底层的 Http 请求连接
  2. 一种方式是使用 HttpComponentsClientHttpRequestFactory 方式,底层使用 HttpClient 访问远程的 Http 服务,使用 HttpClient 可以配置连接池和证书等信息。
二、 使用方法
  1. pom.xml添加依赖
		<!--调用外部网络API使用 start-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5</version>
        </dependency>
        <!--调用外部网络API使用 end-->

        <!--Rest请求start-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.8.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.8</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.8.8</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>
        <!--rest请求end-->
  1. 基于jdk的spring的RestTemplate,配置Config中的bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName" default-lazy-init="true">

    <!--方式一、使用jdk的实现-->
    <bean id="ky.requestFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory">
        <property name="readTimeout" value="10000"/>
        <property name="connectTimeout" value="5000"/>
    </bean>

    <bean id="simpleRestTemplate" class="org.springframework.web.client.RestTemplate">
        <constructor-arg ref="ky.requestFactory"/>
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/plain;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

</beans>
  1. 使用Httpclient连接池的方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName" default-lazy-init="true">

    <!--方式二、使用httpclient的实现,带连接池-->
    <bean id="ky.pollingConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager">
        <!--整个连接池的并发-->
        <property name="maxTotal" value="1000" />
        <!--每个主机的并发-->
        <property name="defaultMaxPerRoute" value="1000" />
    </bean>

    <bean id="ky.httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
        <property name="connectionManager" ref="ky.pollingConnectionManager" />
        <!--开启重试-->
        <property name="retryHandler">
            <bean class="org.apache.http.impl.client.DefaultHttpRequestRetryHandler">
                <constructor-arg value="2"/>
                <constructor-arg value="true"/>
            </bean>
        </property>
        <property name="defaultHeaders">
            <list>
                <bean class="org.apache.http.message.BasicHeader">
                    <constructor-arg value="User-Agent"/>
                    <constructor-arg value="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"/>
                </bean>
                <bean class="org.apache.http.message.BasicHeader">
                    <constructor-arg value="Accept-Encoding"/>
                    <constructor-arg value="gzip,deflate"/>
                </bean>
                <bean class="org.apache.http.message.BasicHeader">
                    <constructor-arg value="Accept-Language"/>
                    <constructor-arg value="zh-CN"/>
                </bean>
            </list>
        </property>
    </bean>

    <bean id="ky.httpClient" factory-bean="ky.httpClientBuilder" factory-method="build" />

    <bean id="ky.clientHttpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
        <constructor-arg ref="ky.httpClient"/>
        <!--连接超时时间,毫秒-->
        <property name="connectTimeout" value="5000"/>
        <!--读写超时时间,毫秒-->
        <property name="readTimeout" value="10000"/>
    </bean>

    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <constructor-arg ref="ky.clientHttpRequestFactory"/>
        <property name="errorHandler">
            <bean class="org.springframework.web.client.DefaultResponseErrorHandler"/>
        </property>
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/plain;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

</beans>
  1. 编写controller,通过testGetAction 和 testPostAction 这两个API来模拟第三方的API
package com.sdu.controller;

import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * call API
 */
@RestController
public class SpringRestTemplateController
{
    @Autowired
    private RestTemplate restTemplate;

    /***********HTTP GET method*************/
    @RequestMapping(value = "/testGetAction",method = RequestMethod.GET)
    public Object getJson()
    {
        JSONObject json = new JSONObject();
        json.put("username", "tester");
        json.put("pwd", "123456748");
        return json;
    }
    @RequestMapping(value = "/getApi",method = RequestMethod.GET)
    public String testGet()
    {
        String url = "http://localhost:8080/testGetAction";
        JSONObject json = restTemplate.getForEntity(url, JSONObject.class).getBody();
        return json.toJSONString();
    }
    /**********HTTP POST method**************/
    @RequestMapping(value = "/testPostAction",method = RequestMethod.POST)
    public Object postJson(@RequestBody JSONObject param)
    {
        System.out.println(param.toJSONString());
        param.put("action", "post");
        param.put("username", "tester");
        param.put("pwd", "123456748");
        return param;
    }
    @RequestMapping(value = "/postApi",method = RequestMethod.POST)
    public Object testPost()
    {
        String url = "http://localhost:8080/testPostAction";
        JSONObject postData = new JSONObject();
        postData.put("descp", "request for post");
        JSONObject json = restTemplate.postForEntity(url, postData, JSONObject.class).getBody();
        return json.toJSONString();
    }

然后在postman上调用getApi,然后查看结果
{“pwd”:“123456748”,“username”:“tester”}
在postman上post 请求 postApi,查看结果
{“action”:“post”,“pwd”:“123456748”,“descp”:“request for post”,“username”:“tester”}

postman 调用API
到这里,我们已经完成了调用Spring API的模拟。

关于Postman的使用,请参考:
Postman 使用方法详解
使用Postman模拟发送get、post、delete、put请求

三、Flask启动服务
  1. 启动 Flask 的 serve
# -*- coding: UTF-8 -*-
# @File    : server.py

import json
import time
from flask import Flask, jsonify
from flask import request

import logger
from Main import Main

logger = logger.logger
app = Flask(__name__, static_url_path="")


@app.route("/healthcheck", methods=['POST', 'GET'])
def test_hello():
    # logger.info("health")
    res = {"message": "hello world!"}
    res_json = jsonify(res)
    return res_json


@app.route("/test", methods=['POST', 'GET'])
def get_data():
    if request.method == 'POST':
        data = request.form.get("data", "")
        logger.info("data: %s" % data)
        try:
            # your code here 对获取的数据进行操作
            # res = function(data)    
            # return jsonify(res)
        except Exception as e:
            # logger.error(e)
            # res = function(data)
            # return jsonify(res)


if __name__ == "__main__":
    my_model = Main()
    app.run(host="127.0.0.1", port=9001, debug=True)
    
  1. 在 spring 中调用该接口
	@RequestMapping(value = "/post_test2",method = RequestMethod.POST)
    public Object post_test2()
    {
        // url
        String url = "http://127.0.0.1:9001/test";
        // headers
        HttpHeaders headers = new HttpHeaders();
		//根据 headers 的类型不同,ContentType 也不同
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // body
        MultiValueMap<String, String> postData = new LinkedMultiValueMap<>();
        postData.add("data", "I m fine.");
        //String postData = "data=I m fine. Are you?";
        HttpEntity<MultiValueMap<String, String>> entity
                = new HttpEntity<>(postData, headers);
        // 根据要求返回数据类型不同,选择 postForObject 或者 postForEntity方法
        //String answer = restTemplate.postForObject(url, entity, String.class);
        //postData.put("data", "I m fine. Are you?");
        JSONObject json = restTemplate.postForEntity(url, postData, JSONObject.class).getBody();
        return json.toJSONString();
        //return answer;
    }

通过spring调用flask

四、参考链接

RestTemplate实践
spring使用RestTemplate来调用其他接口
Spring中使用RestTemplate调用第三方接口API
RestTemplate实践 - Trust_FreeDom
spring mvc - tutorial 1:实现简单的GET、POST接口并使用Postman测试
How to POST form data with Spring RestTemplate? - stackoverflow
POST request via RestTemplate in JSON - stackoverflow
how to get data from ‘ImmutableMultiDict’ in flask - stackoverflow

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值