can @FeignClient extend - and @RestController implement - a common, fully-annotated Interface?

浪尽此生 提交于 2020-01-06 20:17:43

问题


I want a Feign client to consume a Spring Boot controller, and I want the contract between them to be specified in a common Interface to the degree possible.

The interface with method would look something like this:

@RequestMapping
public interface RuleManager {

    @RequestMapping(value = "/addRule", method = RequestMethod.POST, consumes = {"application/json"}, produces = {"application/json"})
    @ResponseBody Rule addRule(@RequestBody Rule rule);
}

The Feign client would look like:

@FeignClient(url = "http://localhost:8080")
public interface RuleManagerClient extends RuleManager { }

and the Spring boot controller:

@RestController
public class RuleManagerService implements RuleManager {

    @Override
    @Transactional
    public Rule addRule(@RequestBody Rule rule) {
        return rule;
    }
}

It's nice that I don't have to specify @RequestMapping in two places, but unfortunately it seems I do have to specify @RequestBody twice. When @RequestBody is omitted from either the controller or the shared interface, the Rule object is instantiated but with all members set to null.

Is there a way around this ? Perhaps this is addressed in a newer version ? My dependencies include:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <exclusions>
            <exclusion>
                <groupId>com.netflix.feign</groupId>
                <artifactId>feign-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>com.netflix.feign</groupId>
        <artifactId>feign-core</artifactId>
        <version>8.14.3</version>
    </dependency>

I discovered this technique required at least feign-core 8.6 here:

https://jmnarloch.wordpress.com/2015/08/19/spring-cloud-designing-feign-client/

Thanks for any help.


回答1:


Apparently this does work--@RequestBody need only appear in the shared Interface. The problem was that I had the following property set in application.properties for the controller but not for the client:

spring.jackson.property-naming-strategy=CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES

That's why the object was instantiated on the server side but with all members null--effectively, the wrong properties were sent across the wire, for example "ruleName" instead of the expected "rule_name".



来源:https://stackoverflow.com/questions/35212960/can-feignclient-extend-and-restcontroller-implement-a-common-fully-annota

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!