If I have a method defined as:

@RequestMapping(value = "/api/events{matrixParam:.*}", method = RequestMethod.GET)
EventList getEvents(@MatrixVariable(pathVar = "matrixParam") Map<String, List<String>> matrixParams)

When I try to call this I get the exception

java.lang.IllegalArgumentException: Illegal character in path at index 35: http://mio-event-service/api/events{matrixParam:.*}
    at java.net.URI.create(URI.java:859)

Which implies that matrix parameters aren't supported. The RequestMapping definating works fine in the severing web app though.

Any ideas?

Thanks

Comment From: nickcodefresh

Looking at line 129 of org.springframework.cloud.netflix.feign.support.SpringMvcContract I see

// TODO: support spring parameter annotations?

So the answer appears to be no at the moment

Comment From: cforce

Would be nie to have that

Nick Smith notifications@github.com schrieb am Do., 22. Okt. 2015 3:19 PM:

Looking at line 129 of org.springframework.cloud.netflix.feign.support.SpringMvcContract I see

// TODO: support spring parameter annotations?

So the answer appears to be no at the moment

— Reply to this email directly or view it on GitHub https://github.com/spring-cloud/spring-cloud-netflix/issues/609#issuecomment-150221269 .

Comment From: nickcodefresh

I'll fork and try to fix

Comment From: mperrault2

@nickcodefresh will your fix include support for @ModelAttribute (as described in #617)? Thanks

Comment From: Dreampie

What time can use @ModelAttribute?

Comment From: Aloren

If someone needs quick workaround for that -- we used custom Encoder in our feign client context:


    @Bean
    public Encoder encoder() {
        Encoder.Default defaultEncoder = new Encoder.Default();
        return new Encoder() {
            @Override
            public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
                if(bodyType == MyCustomParam.class) {
                    encodeCustomParam((MyCustomParam) object, template);
                } else {
                    defaultEncoder.encode(object, bodyType, template);
                }
            }

            private void encodeCustomParam(MyCustomParam object, RequestTemplate template) {
                    MyCustomParam param = ((MyCustomParam) object);
                    template.query("var1", String.valueOf(param.var1));
                    template.query("var2", String.valueOf(param.var2));
            }
        };
    }

and method in feign client:

    @RequestMapping(method = GET, value = "/api", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    MyCustomResponse getByCustomParam(MyCustomParam param);

Comment From: sify21

To make @Aloren 's answer more generic, one can use reflection and annotation-processing

    @Bean
    public Encoder encoder() {
        Encoder defaultEncoder = new Encoder.Default();
        return (object, bodyType, template) -> {
            Class clazz= (Class)bodyType;
            if (clazz.getAnnotation(MyModelAttributes.class) != null) {
                for (Field field : clazz.getDeclaredFields()) {
                    field.setAccessible(true);
                    try {
                        Object data = field.get(object);
                        if(data == null) continue;
                        if(field.getType().getName().equals("java.util.List")){
                            List<String> s = new ArrayList<>();
                            for(Object o : (List<?>) data){
                                s.add(o.toString());
                            }
                            template.query(field.getName(), s.toArray(new String[]{}));
                        } else {
                            template.query(field.getName(), data.toString());
                        }
                    } catch (IllegalAccessException e) {
                        continue;
                    }
                }
            } else {
                defaultEncoder.encode(object, bodyType, template);
            }
        };
    }

and put @MyModelAttributes on MyCustomParam class.

Comment From: littlefisher666

Mark. I want to use @ModelAttribute too.

Comment From: Dreampie

maybe you need this. https://stackoverflow.com/questions/35621062/how-to-custom-feignclient-expander-to-convert-param/35835085?noredirect=1#comment86877708_35835085

Comment From: littlefisher666

Thank you for your provide.I make a @JsonArguments in Feign but @ModelAttribute is not useful in controller. Can you give me some advice?

Comment From: littlefisher666

@Dreampie Hi, I code a @JsonArguments like your provide. The url is : http://192.168.31.140:8081/api/v1/asset/repay-plan/page?request=%7B%22pageNum%22%3A1%2C%22pageSize%22%3A15%2C%22loanInvoiceId%22%3A%22111%22%7D But it is can't be use in controller. Could you please provide a full code which I can learn?