Spring Cloud feign服务间调用的多种参数共同传输问题

  • 需求:通过zuul服务网关进行服务间资源调用与接口调用,试过的方法太多,找到很多疑点,现在终于定位,首先记录,成功的案例:
  • 消费者controller
@ApiOperation(value = "用户注册",notes = "用户注册")

    @ApiImplicitParams({
            @ApiImplicitParam(type = "query", name = "name",value = "用户名",required = true),
            @ApiImplicitParam(type = "query", name = "password",value = "密码",required = true),
            @ApiImplicitParam(type = "query", name = "deptId",value = "所属方向ID",required = true),
            @ApiImplicitParam(type = "query", name = "grade",value = "年级,比如2018",required = true),
            @ApiImplicitParam(type = "query", name = "email",value = "邮箱,确保格式正确",required = true),
            @ApiImplicitParam(type = "query", name = "mobile",value = "手机,确保格式正确",required = true),
    })
    @PostMapping("/register")
    @CrossOrigin(origins = "*", allowCredentials = "true",allowedHeaders = "*",methods = {RequestMethod.GET, RequestMethod.DELETE, RequestMethod.HEAD, RequestMethod.OPTIONS, RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH})
    public HttpResult register(String name, String password, Long deptId, String grade, String email, String mobile, @RequestParam List<Long> roleList, MultipartFile uploadFile  ) throws FileNotFoundException {
        System.out.println("112121");
        for(Long a : roleList){
            System.out.println("role:"+a);
        }
        return   sysUserService.register(name, password, deptId, grade, email, mobile, roleList, uploadFile);

    }
  • 消费者service层
@FeignClient(name = "hcnet-website-1",contextId = "i")
@RequestMapping("/user")
public interface SysUserService {



    @RequestMapping(value = "/register",method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public HttpResult register(@RequestParam String name,@RequestParam String password,@RequestParam Long deptId,@RequestParam String grade,@RequestParam String email,@RequestParam String mobile,
                               @RequestParam List<Long> roleList,@RequestBody MultipartFile uploadFile);
  • 生产者controller
@Api(tags = "用户信息接口")
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private SysUserService sysUserService;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    //private String url = "/usr/local/spring";

    @ApiOperation(value = "用户注册",notes = "用户注册")

    @ApiImplicitParams({
            @ApiImplicitParam(type = "query", name = "name",value = "用户名",required = true),
            @ApiImplicitParam(type = "query", name = "password",value = "密码",required = true),
            @ApiImplicitParam(type = "query", name = "deptId",value = "所属方向ID",required = true),
            @ApiImplicitParam(type = "query", name = "grade",value = "年级,比如2018",required = true),
            @ApiImplicitParam(type = "query", name = "email",value = "邮箱,确保格式正确",required = true),
            @ApiImplicitParam(type = "query", name = "mobile",value = "手机,确保格式正确",required = true),
    })
    @PostMapping("/register")
    @CrossOrigin(origins = "*", allowCredentials = "true",allowedHeaders = "*",methods = {RequestMethod.GET, RequestMethod.DELETE, RequestMethod.HEAD, RequestMethod.OPTIONS, RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH})
    public HttpResult register(String name, String password, Long deptId, String grade, String email, String mobile, @RequestParam List<Long> roleList, MultipartFile uploadFile  ) throws FileNotFoundException {
        //MultipartFile uploadFile = null;
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>cn.hcnet2006.blog</groupId>
        <artifactId>blog-base</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>cn.hcnet2006.blog</groupId>
    <artifactId>micro-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>micro-consumer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.2.2</spring-boot-admin.version>
        <docker.image.prefix>47.97.170.173:5000</docker.image.prefix>
    </properties>

    <dependencies>

        <!-- 使用Apache HttpClient替换Feign原生httpclient -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
            <version>${spring-boot-admin.version}</version>
        </dependency>
        <!--Swagger2文档-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--添加消息总线依赖-->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!--使用Maven和Dockerfile命令构建镜像-->
            <plugin>

                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <!--生成镜像名称-->
                    <repository>
                        ${docker.image.prefix}/${project.name}
                    </repository>
                    <!--生成镜像版本-->
                    <tag>${project.version}</tag>
                    <!--推送到私有仓库或者DockerHub时需要开启用户认证-->
                    <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                        <JAR_EXPOSE>8204</JAR_EXPOSE>
                    </buildArgs>
                </configuration>
                <!--直接使用 mvn install 命令打包项目, 就会自动构建并推送镜像-->
                <executions>
                    <execution>
                        <id>default</id>
                        <phase>install</phase>
                        <goals>
                            <goal>build</goal>
                            <goal>push</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

  • application.yml
server:
  port: 8209
spring:
  application:
    name: micro-consumer
  cloud:
    consul:
      host: 172.17.0.1
      port: 8500
      discovery:
        service-name: ${spring.application.name}
        hostname: 172.17.0.1
        health-check-url: http://172.17.0.1:8209/actuator/health

  servlet:
    multipart:
      enabled: true
      file-size-threshold: 0
      max-file-size: 1000MB
      max-request-size: 1000MB
      resolve-lazily: false
  boot:
    admin:
      client:
        url: "http://172.17.0.1:8205"


management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always


feign:
  client:
    config:
      default:
        connectTimeout: 500000
        readTimeout: 500000
        loggerLevel: basic

  • 服务间token传输设置
package cn.hcnet2006.blog.microconsumer.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Configuration
public class FeignHeadersInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        HttpServletRequest request = getHttpServletRequest();
        if(Objects.isNull(request)){
            return;
        }
        Map<String,String> headers = getHeaders(request);
        if(headers.size() > 0){
            Iterator<Map.Entry<String,String>> iterator = headers.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String, String> entry = iterator.next();
                //把原来的head请求头,原样设置到feign请求头中
                //包括token
                if(entry.getKey() == "authorization" || entry.getKey().equalsIgnoreCase("authorization")){
                    requestTemplate.header(entry.getKey(), entry.getValue());
                }
            }
        }
    }
    private HttpServletRequest getHttpServletRequest(){
        try{
            return ((ServletRequestAttributes)(RequestContextHolder.currentRequestAttributes())).getRequest();
        }catch (Exception e){
            return null;
        }
    }
    private Map<String, String> getHeaders(HttpServletRequest request){
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enums = request.getHeaderNames();
        while(enums.hasMoreElements()){
            String key = enums.nextElement();
            String value = request.getHeader(key);
            map.put(key,value);
        }
        return map;
    }
}

发布了96 篇原创文章 · 获赞 45 · 访问量 7291

猜你喜欢

转载自blog.csdn.net/weixin_43404791/article/details/105116307