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添加依赖
		
        <dependency>
            <groupId>org.apache.httpcomponentsgroupId>
            <artifactId>httpclientartifactId>
            <version>4.5version>
        dependency>
        

        
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>2.8.8version>
        dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-coreartifactId>
            <version>2.8.8version>
        dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-annotationsartifactId>
            <version>2.8.8version>
        dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformatgroupId>
            <artifactId>jackson-dataformat-xmlartifactId>
            <version>2.8.8version>
        dependency>

        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>1.2.28version>
        dependency>
        
  1. 基于jdk的spring的RestTemplate,配置Config中的bean

<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">

    
    <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-8value>
                        list>
                    property>
                bean>
            list>
        property>
    bean>

beans>
  1. 使用Httpclient连接池的方式

<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">

    
    <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-8value>
                        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”}

Spring使用RestTemplate调用Flask接口API_第1张图片
到这里,我们已经完成了调用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使用RestTemplate调用Flask接口API_第2张图片

四、参考链接

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

你可能感兴趣的:(Java,Spring)