springboot 的Feign,okhttp

feign 的简介

feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。
feign强调服务之间的调用
一 服务提供者准备

  • application.yml 配置
server:
port: 8602

spring:
application:
name: testservice

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8800/eureka/

app:
ip: localhost
  • DTO准备
    创建共用的ResponseDTO:Result.java
public class result{
private int code;

private String message;

private Object content;

private String serviceName;

private String host;

public int getCode() {
    return code;
}

public void setCode(int code) {
    this.code = code;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public Object getContent() {
    return content;
}

public void setContent(Object content) {
    this.content = content;
}

public String getServiceName() {
    return serviceName;
}

public void setServiceName(String serviceName) {
    this.serviceName = serviceName;
}

public String getHost() {
    return host;
}

public void setHost(String host) {
    this.host = host;
}

}

创建Plus.java用作加法运算RequestDTO

public class Plus {
private int numA;

private int numB;

public int getNumA() {
    return numA;
}

public void setNumA(int numA) {
    this.numA = numA;
}

public int getNumB() {
    return numB;
}

public void setNumB(int numB) {
    this.numB = numB;
}

}
  • 编写服务入口
    创建服务入口 TestController.java
@RestController
public class TestController {
@Value("${spring.application.name}")
private String serviceName;

@Value("${app.ip}")
private String address;

@Value("${server.port}")
private String port;

@RequestMapping("/")
public Object index() {
    Result result = new Result();
    result.setServiceName(serviceName);
    result.setHost(String.format("%s:%s", address, port));
    result.setMessage("hello");
    return result;
}

@RequestMapping("/plus")
public Object plus(Plus plus) {
    Result result = new Result();
    result.setServiceName(serviceName);
    result.setHost(String.format("%s:%s", address, port));
    result.setMessage("success");
    result.setContent(plus.getNumA() + plus.getNumB());
    return result;
}

@RequestMapping("/plus2")
public Object plus2(@RequestBody Plus plus) {
    Result result = new Result();
    result.setServiceName(serviceName);
    result.setHost(String.format("%s:%s", address, port));
    result.setMessage("success");
    result.setContent(plus.getNumA() + plus.getNumB());
    return result;
}


}
  • 访问测试

启动TestService
分别以端口8602,8603启动testservice。 此时testservice等于是在Eureka Server注册了两个实例

分别访问 http://localhost:8602,http://localhost:8603

二、服务消费者搭建(Feign)

  • 创建Feign项目
    在pom.xml加入相关依赖
<groupId>io.ken.springcloud.feignclient</groupId>
<artifactId>feignclient</artifactId>
<version>1.0-SNAPSHOT</version>

<name>feignclient</name>
<url>http://ken.io</url>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.BUILD-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>

</dependencies>

<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/libs-snapshot</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

<build>
    <finalName>feignclient</finalName>
</build>
  • 配置Eureka Client:application.yml
server:
port: 8605

spring:
application:
name: feignclient

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8800/eureka/
  • 配置Fegin启动类
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class App {

public static void main(String[] args) {
    SpringApplication.run(App.class, args);
}
}
  • 创建共用的ResponseDTO:Result.java
  • 创建Plus.java作为加法运算RequestDTO
public class Result {

private int code;

private String message;

private Object content;

private String serviceName;

private String host;

public int getCode() {
    return code;
}

public void setCode(int code) {
    this.code = code;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public Object getContent() {
    return content;
}

public void setContent(Object content) {
    this.content = content;
}

public String getServiceName() {
    return serviceName;
}

public void setServiceName(String serviceName) {
    this.serviceName = serviceName;
}

public String getHost() {
    return host;
}

public void setHost(String host) {
    this.host = host;
}
}
public class Plus {

private int numA;

private int numB;

public int getNumA() {
    return numA;
}

public void setNumA(int numA) {
    this.numA = numA;
}

public int getNumB() {
    return numB;
}

public void setNumB(int numB) {
    this.numB = numB;
}
}
  • 编写Eureka服务访问
import io.ken.springcloud.feignclient.model.Plus;
import io.ken.springcloud.feignclient.model.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = "testservice")
public interface TestService {

@RequestMapping(value = "/", method = RequestMethod.GET)
String indexService();

@RequestMapping(value = "/plus", method = RequestMethod.GET)
Result plusService(@RequestParam(name = "numA") int numA, @RequestParam(name = "numB") int numB);

@RequestMapping(value = "/plus", method = RequestMethod.POST, consumes = "application/json")
Result plusabService(Plus plus);

@RequestMapping(value = "/plus2", method = RequestMethod.POST)
Result plus2Service(@RequestBody Plus plus);
}
  • 编写服务入口:创建 TestController.java 作为访问testservice的入口
import io.ken.springcloud.feignclient.model.Plus;
import io.ken.springcloud.feignclient.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

@Autowired
private TestService testService;

@RequestMapping("/")
public Object index() {
    return "feign client";
}

@RequestMapping("/ti")
public Object ti() {
    return testService.indexService();
}

@RequestMapping("/plus")
public Object plus(@RequestParam("numa") int numA, @RequestParam("numb") int numB) {
    return testService.plusService(numA, numB);
}

@RequestMapping("/plusab")
public Object plusA(@RequestParam("numa") int numA, @RequestParam("numb") int numB) {
    Plus plus = new Plus();
    plus.setNumA(numA);
    plus.setNumB(numB);
    return testService.plusabService(plus);
}

@RequestMapping("/plus2")
public Object plus2(Plus plus) {
    return testService.plus2Service(plus);
}
}
  • 服务消费/访问测试
    FeignClient项目启动后,访问 http://localhost:8605/ti 会交替显示以下内容
{
"code": 0,
"message": "hello",
"content": null,
"serviceName": "testservice",
"host": "localhost:8602"
}

{
"code": 0,
"message": "hello",
"content": null,
"serviceName": "testservice",
"host": "localhost:8603"
}

okhttp简介

OkHttp是一个开源的Java/Android HTTP客户端库,它由Square公司开发并维护。OkHttp的目标是成为一个快速、高效、可扩展且易于使用的HTTP客户端库,为Android应用程序提供网络访问的支持。
使用OkHttp,我们可以轻松地完成一些常见的HTTP操作,如GET和POST请求,并进行文件上传和下载。它还支持异步请求和同步请求,并包含有用的功能,如重试请求、缓存响应和加密通信。
更强调,调取第三方接口
更好的http客户端:https://mp.weixin.qq.com/s/iXVAIz_H8eMRZADLlQL6wA

创建一个配置类

@Configuration
public class OkHttpClientConfig {
 
    @Bean
    public OkHttpClient okHttpClient() {
        return new OkHttpClient();
    }
}

创建一个Service类,使用@Autowired注解将OkHttpClient注入:

@Service
public class ApiService {
 
    private final OkHttpClient okHttpClient;
 
    public ApiService(@Autowired OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }
 
    public String sendRequest(String url) throws IOException {
        Request request = new Request.Builder().url(url).build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            return Objects.requireNonNull(response.body()).string();
        }
    }
}

最后,在控制器中调用该Service:

@RestController
public class ApiController {
 
    private final ApiService apiService;
 
    public ApiController(@Autowired ApiService apiService) {
        this.apiService = apiService;
    }
 
    @GetMapping("/get")
    public String getData() throws IOException {
        String url = "http://example.com/data";
        return apiService.sendRequest(url);
    }
}

关于okhttp的其他类型请求

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import okhttp3.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.HashMap;
import java.util.Map;
 
@RestController
@RequestMapping("okhttp")
public class OkHttpController {
 
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private static final MediaType XML = MediaType.parse("application/xml; charset=utf-8");
 
    private OkHttpClient client = new OkHttpClient();
 
    /**
     * get请求
      * @return
     */
    @RequestMapping("get")
    public String Get(){
        String url = "http://localhost:36247/weatherforecast/string";
        Request request = new Request.Builder()
                .url(url)
                .build();
        try{
            Response response = client.newCall(request).execute();
            return response.body().string();
        }catch (Exception e){
            throw  new RuntimeException("HTTP GET同步请求失败 URL:"+url,e);
        }
    }
 
    /**
     * get请求
     * @return
     */
    @RequestMapping("getUser")
    public String GetUser(){
        String url = "http://localhost:36247/weatherforecast/getuser?name=admin_get&password=123456_get";
        Request request = new Request.Builder()
                .url(url)
                .build();
        try{
            Response response = client.newCall(request).execute();
            return response.body().string();
        }catch (Exception e){
            throw  new RuntimeException("HTTP GET同步请求失败 URL:"+url,e);
        }
    }
 
    /**
     * post 请求
     * FormData 参数
     * @return
     */
    @RequestMapping("postForm")
    public String PostForm(){
        String url = "http://localhost:36247/weatherforecast/form";
 
        FormBody.Builder form = new FormBody.Builder();
        form.add("name","admin_form");
        form.add("password","123456_form");
 
        Request request = new Request.Builder()
                .url(url)
                .post(form.build())
                .build();
        try{
            Response response = client.newCall(request).execute();
            return response.body().string();
        }catch (Exception e){
            throw  new RuntimeException("HTTP GET同步请求失败 URL:"+url,e);
        }
    }
 
    /**
     * post 请求
     * JSON 参数
     * @return
     */
    @RequestMapping("postJson")
    public String PostJson(){
        String url = "http://localhost:36247/weatherforecast";
 
        /**
         * OK
         */
        JSONObject json = new JSONObject();
        json.put("name","admin_json");
        json.put("password","123456_json");
 
        /**
         * OK
         */
        Map<String,Object> map = new HashMap<>();
        map.put("name","admin_map");
        map.put("password","123456_map");
 
        RequestBody requestBody = RequestBody.create(JSON,String.valueOf(json));
        //RequestBody requestBody = RequestBody.create(JSON,new Gson().toJson(map));
 
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        try{
            Response response = client.newCall(request).execute();
            return response.body().string();
        }catch (Exception e){
            throw  new RuntimeException("HTTP POST请求失败 URL:"+url,e);
        }
    }
}
``
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值