0

最后经过大量的堆栈溢出 ;-) 和调试后,我让它工作了:我的 Feign 客户端可以在 Spring-Data-Rest 的 API 上发出请求,我得到了一个Resource<Something>填充links

到目前为止我的代码...

FeignClient:

@FeignClient(name = "serviceclient-hateoas",
    url = "${service.url}",
    decode404 = true,
    path = "${service.basepath:/api/v1}",
    configuration = MyFeignHateoasClientConfig.class)
public interface MyFeignHateoasClient {

    @RequestMapping(method = RequestMethod.GET, path = "/bookings/search/findByBookingUuid?bookingUuid={uuid}")
    Resource<Booking> getBookingByUuid(@PathVariable("uuid") String uuid);

}

客户端配置:

@Configuration
public class MyFeignHateoasClientConfig{

    @Value("${service.user.name:bla}")
    private String serviceUser;

    @Value("${service.user.password:blub}")
    private String servicePassword;

    @Bean
    public BasicAuthRequestInterceptor basicAuth() {
        return new BasicAuthRequestInterceptor(serviceUser, servicePassword);
    }

    @Bean
    public Decoder decoder() {
        return new JacksonDecoder(getObjectMapper());
    }

    @Bean
    public Encoder encoder() {
        return new JacksonEncoder(getObjectMapper());
    }

    public ObjectMapper getObjectMapper() {
        return new ObjectMapper()
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                .registerModule(new Jackson2HalModule());
    }

    @Bean
    public Logger logger() {
        return new Slf4jLogger(MyFeignHateoasClient.class);
    }

    @Bean
    public Logger.Level logLevel() {
        return Logger.Level.FULL;
    }
}

在通过 jar 依赖使用客户端的应用程序中:

@SpringBootApplication
@EnableAutoConfiguration
@EnableFeignClients(basePackageClasses=MyFeignHateoasClient.class)
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
@ComponentScan(excludeFilters = @Filter(type = ... ), basePackageClasses= {....class}, basePackages="...")
public class Application {
...

现在这是有效的:

@Autowired
private MyFeignHateoasClient serviceClient;
...
void test() {
    Resource<Booking> booking = serviceClient.getBookingByUuid(id);
    Link link = booking.getLink("relation-name");
}

现在我的问题:

我如何从这里继续,即导航到链接中的资源?

该链接包含我要请求的资源的 URL。

  • 我真的必须从 URL 中解析出 ID 并向 FeignClient 添加一个方法,比如getRelationById(id)
  • 至少有一种方法可以将完整的资源 URL 传递给 FeignClient 的方法吗?

我没有找到演示如何从这里开始的示例(尽管进行了 POST/修改)。任何提示表示赞赏!

谢谢

4

1 回答 1

0

我目前的解决方案:

我在 Feign 客户端中添加了一个额外的请求,采用了整个资源路径:

...
public interface MyFeignHateoasClient {
...
    @RequestMapping(method = RequestMethod.GET, path = "{resource}")
    Resource<MyLinkedEntity> getMyEntityByResource(@PathVariable("resource") String resource);
}

然后我实现了某种“HAL-Tool”:

...                                                                                                                                                                              
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

import org.springframework.hateoas.Link;

import feign.Target;
import lombok.SneakyThrows;

public class HalTool {

    private Object feignClient;

    public static HalTool forClient( Object feignClient ) {
        return new HalTool(feignClient);
    }

    private HalTool( Object feignClient ) {
        this.feignClient = feignClient;
    }

    @SneakyThrows
    private String getUrl() {
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(feignClient);
        Field target = invocationHandler.getClass().getDeclaredField("target");
        target.setAccessible(true);
        Target<?> value = (Target<?>) target.get(invocationHandler);
        return value.url();
    }

    public String toPath( Link link ) {
        String href = link.getHref();
        String url = getUrl();
        int idx = href.indexOf(url);
        if (idx >= 0 ) {
            idx += url.length();
        }
        return href.substring(idx);
    }
}                                                                                                                                                                                         

然后我可以请求这样的链接资源:

Link link = booking.getLink("relation-name");
Resource<MyLinkedEntity> entity = serviceClient.getMyEntityByResource(
    HalTool.forClient(serviceClient).toPath(link));
于 2017-12-21T16:12:24.647 回答