【问题标题】:Preserving hostname on HATEOAS Resource with OpenFeign使用 OpenFeign 在 HATEOAS 资源上保留主机名
【发布时间】:2019-09-14 05:27:51
【问题描述】:

我正在尝试使用 OpenFeign 和 ResourceAssembler 将 URI 添加到位于不同微服务中的资源,同时保留原始请求中的主机名。

向另一个微服务中的 HATEOAS 资源发出 REST 请求时,resource.getId() 方法会返回一个链接,其中主机名是 Docker 容器哈希,而不是用于发出请求的原始主机名。

控制器

@RestController
@RequestMapping("/bulletins")
public class BulletinController {
// Autowired dependencies

    @GetMapping(produces = MediaTypes.HAL_JSON_VALUE)
    public ResponseEntity<PagedResources<BulletinResource>> getBulletins(Pageable pageable) {
        Page<Bulletin> bulletins = bulletinRepository.findAll(pageable);

        return ResponseEntity.ok(pagedResourceAssembler.toResource(bulletins, bulletinResourceAssembler));
    }
}

汇编程序

@Component
public class BulletinResourceAssembler extends ResourceAssemblerSupport<Bulletin, BulletinResource> {
    private final AdministrationService administrationService;

    @Autowired
    public BulletinResourceAssembler(AdministrationService administrationService) {
        super(BulletinController.class, BulletinResource.class);
        this.administrationService = administrationService;
    }

    @Override
    public BulletinResource toResource(Bulletin entity) {
        Resource<Site> siteRessource = administrationService.getSiteBySiteCode(entity.getSiteCode());

        \\ Set other fields ...

        bulletinRessource.add(siteRessource.getId().withRel("site"));
        return bulletinRessource;
    }
}

Feign 客户端

@FeignClient(name = "${feign.administration.serviceId}", path = "/api")
public interface AdministrationService {

    @GetMapping(value = "/sites/{siteCode}")
    Resource<Site> getSiteBySiteCode(@PathVariable("siteCode") String siteCode);

}

公告资源

@Data
public class BulletinResource extends ResourceSupport {
// fields
}

预期结果
卷曲http://myhost/api/bulletins

{
  "_embedded" : {
    "bulletinResources" : [ {
      "entityId" : 1,
      "_links" : {
        "self" : {
          "href" : "http://myhost/api/bulletins/1"
        },
        "site" : {
          "href" : "http://myhost/api/sites/000"
        }
      }
    } ]
  },
  [...]
}

实际结果
卷曲http://myhost/api/bulletins

{
  "_embedded" : {
    "bulletinResources" : [ {
      "entityId" : 1,
      "_links" : {
        "self" : {
          "href" : "http://myhost/api/bulletins/1"
        },
        "site" : {
          "href" : "http://b4dc1a02586c:8080/api/sites/000"
        }
      }
    } ]
  },
  [...]
}

请注意站点的 href 是 b4dc1a02586c,这是 Docker 容器 ID。

【问题讨论】:

    标签: microservices spring-cloud spring-cloud-feign


    【解决方案1】:

    解决方案是为 FeignClient 手动定义一个 RequestInterceptor 并手动添加 X-Forwarded-Host 标头,并在发出请求的服务中定义一个 ForwardedHeaderFilter bean。

    客户端

    public class ForwardHostRequestInterceptor implements RequestInterceptor {
    
        private static final String HOST_HEADER = "Host";
        private static final String X_FORWARDED_HOST = "X-Forwarded-Host";
    
        @Override
        public void apply(RequestTemplate requestTemplate) {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes();
    
            if (requestAttributes == null) {
                return;
            }
    
            HttpServletRequest request = requestAttributes.getRequest();
            String host = request.getHeader(X_FORWARDED_HOST);
            if (host == null) {
                host = request.getHeader(HOST_HEADER);
            }
    
            requestTemplate.header(X_FORWARDED_HOST, host);
        }
    
    }
    

    生产方

    生产方也需要根据https://github.com/spring-projects/spring-hateoas/issues/862的讨论进行修改
    参考以下文档
    https://docs.spring.io/spring-hateoas/docs/current-SNAPSHOT/reference/html/#server.link-builder.forwarded-headers
    哪些状态需要添加以下 bean 以使用前向标头。

    @Bean
    ForwardedHeaderFilter forwardedHeaderFilter() {
        return new ForwardedHeaderFilter();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2020-12-29
      相关资源
      最近更新 更多