SpringCloud 远程消费( Feign 远程调用&& DTO 层的构建)

前言:继上一篇博客的基础上在进行的编码

SpringCloud 的基本使用 nacosSpringCloud 基本使用与 nacos_m0_58525944的博客-CSDN博客

一,Feign 远程调用  消费者(consumer) 生产者(provider)

1,定义远程调用接口  在生产者  建立pojo软件包,新建User实体类

package com.provider.nacos_provider.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @author lgs
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class User {

    private String account;
    private String password;

}

2,提供接口用于消费者调用   在生产者中创建controller层

其中远程调用三种传参方式

①.@PathVariable 路径传参        ②.@RequestParam 请求参数传参

③.@RequestBody   json传参

package com.provider.nacos_provider.controller;

import com.lgs.commons.dto.UserDto;
import com.provider.nacos_provider.pojo.User;
import javassist.runtime.DotClass;
import ma.glasnost.orika.MapperFactory;
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @author T440s
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private MapperFactory factory;

//  路径传参
    @RequestMapping("/{account}")
    public String getByPath(@PathVariable String account){
        System.out.println("account:"+account);
        return "provider say : yes";
    }

//  请求直接携带
    @RequestMapping("/param")
    public String getByParam(@RequestParam("account") String account, @RequestParam("password") String password){
        System.out.println("account:"+account+"\tpassword:"+password);
        return "provider say : yes";
    }

//  jxon格式
    @RequestMapping("/pojo")
    public String getByPojo(@RequestBody UserDto userDto){
        User u = new User();
        u.setAccount(userDto.getAccount()).setPassword(userDto.getPassword());

//        只适应属于一样的
//        User u = factory.getMapperFacade().map(userDto,User.class);

//        属性不一样  生产者为name  dto里面为account
//        factory.classMap(UserDto.class,User.class)
//                .field("name","account")
//                .byDefault().register();
//        User map = factory.getMapperFacade().map(userDto,User.class);

        System.out.println("pojo:"+userDto);
        return "provider say : yes";
    }

//  所有格式
    @RequestMapping("/more")
    public String getByMore(@RequestBody Map<String,Object> map){
        System.out.println("more:"+map);
        return "provider say : yes";
    }

}

3,在消费者模块中添加接口

注解@FeignClient("/nacos-provider")表示远程通信,括号内
package com.consumer.cloud_consumer.service;

import com.lgs.commons.dto.UserDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @author lgs
 *
 * FeignClient  远程通信
 */
@FeignClient("nacos-provider")
@SuppressWarnings("all")
public interface FeignUserService {

//  路径传参
    @RequestMapping("/user/{account}")
    public String getByPath(@PathVariable(value = "account") String account);

//  请求直接携带
    @RequestMapping("/user/param")
    public String getByParam(@RequestParam("account") String account, @RequestParam("password") String password);


//  jxon格式
    @RequestMapping("/user/pojo")
    public String getByPojo(@RequestBody UserDto user);

//  所有格式
    @RequestMapping("/user/more")
    public String getByMore(@RequestBody Map<String,Object> map);

}

4,在启动类中添加注解  开启远程通信  

@EnableDiscoveryClient

5,测试时,我们需把生产者中的user类复制一份到消费者中

6,开始远程调用,在消费者创建controller层进行测试

package com.consumer.cloud_consumer.controller;

import com.consumer.cloud_consumer.service.FeignUserService;
import com.lgs.commons.dto.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private FeignUserService service;

    @RequestMapping("/test01")
    public String test01(String account){
        service.getByPath(account);
        return "yes";
    }

    @RequestMapping("/{account}")
    public String test02(@PathVariable String account){
        service.getByPath(account);
        return "yes";
    }

    @RequestMapping("/test03")
    public String test03(String account,String password){
        service.getByParam(account,password);
        return "yes";
    }

    @RequestMapping("/test04")
    public String test04(String account,String password){
        service.getByPojo(new UserDto().setAccount(account).setPassword(password));
        return "yes";
    }

    @RequestMapping("/test05")
    public String test05(String account,String password){
        Map<String,Object> map = new HashMap<>();
        map.put("account",account);
        map.put("password",password);
        service.getByMore(map);
        return "yes";
    }

}

测试:

 二,DTO 层的构建

消费者调用接口时,需要使用到user实体类,这就使得代码重复,为了使代码简介,我们采取dot层的构建

1,DTO封装介绍

1.VO(View Object):视图对象,用于展示层,前端将数据传到后台

2.DTO(Data Transfer Object):数据传输对象,用于后端服务互相传数据

3.DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。用于服务调用service层

4.PO(Persistent Object):持久化对象,用于service调用数据库

关系图:

消费者 远程调用 生产者 : 需要网络传输 , 使用 DTO 同一封装对象
原理与 SpringBoot 启动类相同
1. DTO 对象封装到公共 DTO 模块
2. 为需要的项目引入公共 DTO 模块
注意点
1. 不需要继承父模块 ( 重复引用问题 )
2. 打包方式为 jar
3. 不需要添加启动类的编译

2,在父项目中新建一个子项目,版本为2.4.1

3,在这个 commons 的 pom 文件中导入 lombok 依赖  如果有很多子项目要用,就放到父项目中

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

4,将dot模块变成jar包的形式,使得其他模块可导入pom文件添加依赖

5,父模块pom文件中添加dot依赖并进行单方面认亲

    <dependency>
      <groupId>com.lgs</groupId>
      <artifactId>commons</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>

然后消费者中的user类就可以删除,并在使用过user类的地方用userdto代替

在这里会产生一个问题:dto类的属性比user中的多,或者字段名不一样

有以下两种解决方式:

①拿到user类,然后去修改属性值,但字段过多就不适用了

User u = new User();
u.setAccount(userDto.getAccount()).setPassword(userDto.getPassword());

②orika 对象复制

生产者pom文件中添加依赖

<dependency>
    <groupId>ma.glasnost.orika</groupId>
    <artifactId>orika-core</artifactId>
    <version>1.4.6</version>
</dependency>

在生产者的启动类中对MapperFactory属性进行spring注入

@Scope("prototype")表示原型链模式(为了使MapperFactory互不干涉)

@Bean
@Scope("prototype")
public MapperFactory mapperFactory(){
    return new DefaultMapperFactory.Builder().build();
}
//只适应属于一样的
User u = factory.getMapperFacade().map(userDto,User.class);

//属性不一样  生产者为name  dto里面为account
factory.classMap(UserDto.class,User.class)
        .field("name","account")
        .byDefault().register();
User map = factory.getMapperFacade().map(userDto,User.class);

OK!到这就结束了,希望能帮到你!!!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亣柒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值