最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

spring - convert.ConverterNotFoundException: No converter found capable [@annotation.RequestParam com.example.MyQueryParameters]

programmeradmin0浏览0评论

I have the following HttpExchange interface:

@HttpExchange(accept = "application/json", contentType = "application/json")
public interface MyHttpExchange {

    @GetExchange("/api/v1.0/question")
    Mono<String> question(@RequestParam MyQueryParameters myQueryParameters);

}

Here is the object, for simplicity here, I am leaving out three fields, but imagine much more than that.

public record MyQueryParameters(int id, int name, int age) {
}

With this new HttpExchange interface, I would like to query an external rest API, which accepts request query parameters

.0/question?id=1&name=11&age=111

I would expect this to work. However, I am facing this issue:

.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [@.springframework.web.bind.annotation.RequestParam com.example.MyQueryParameters] to type [java.lang.String]
    at .springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:294) ~[spring-core-6.2.3.jar:6.2.3]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ HTTP GET "..." [ExceptionHandlingWebHandler]
Original Stack Trace:
        at .springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:294) ~[spring-core-6.2.3.jar:6.2.3]
        at .springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:185) ~[spring-core-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.AbstractNamedValueArgumentResolver.addSingleValue(AbstractNamedValueArgumentResolver.java:199) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.AbstractNamedValueArgumentResolver.addSingleOrMultipleValues(AbstractNamedValueArgumentResolver.java:179) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.AbstractNamedValueArgumentResolver.resolve(AbstractNamedValueArgumentResolver.java:97) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.HttpServiceMethod.applyArguments(HttpServiceMethod.java:142) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.HttpServiceMethod.invoke(HttpServiceMethod.java:132) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.HttpServiceProxyFactory$HttpServiceMethodInterceptor.invoke(HttpServiceProxyFactory.java:243) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
        at .springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.3.jar:6.2.3]
        at jdk.proxy2/jdk.proxy2.$Proxy52.question(Unknown Source) ~[na:na]

How to properly use HttpExchange interface with an object (not the Map<String, Object>)?

I have the following HttpExchange interface:

@HttpExchange(accept = "application/json", contentType = "application/json")
public interface MyHttpExchange {

    @GetExchange("/api/v1.0/question")
    Mono<String> question(@RequestParam MyQueryParameters myQueryParameters);

}

Here is the object, for simplicity here, I am leaving out three fields, but imagine much more than that.

public record MyQueryParameters(int id, int name, int age) {
}

With this new HttpExchange interface, I would like to query an external rest API, which accepts request query parameters

https://third-party/api/v1.0/question?id=1&name=11&age=111

I would expect this to work. However, I am facing this issue:

.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [@.springframework.web.bind.annotation.RequestParam com.example.MyQueryParameters] to type [java.lang.String]
    at .springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:294) ~[spring-core-6.2.3.jar:6.2.3]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ HTTP GET "..." [ExceptionHandlingWebHandler]
Original Stack Trace:
        at .springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:294) ~[spring-core-6.2.3.jar:6.2.3]
        at .springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:185) ~[spring-core-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.AbstractNamedValueArgumentResolver.addSingleValue(AbstractNamedValueArgumentResolver.java:199) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.AbstractNamedValueArgumentResolver.addSingleOrMultipleValues(AbstractNamedValueArgumentResolver.java:179) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.AbstractNamedValueArgumentResolver.resolve(AbstractNamedValueArgumentResolver.java:97) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.HttpServiceMethod.applyArguments(HttpServiceMethod.java:142) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.HttpServiceMethod.invoke(HttpServiceMethod.java:132) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.web.service.invoker.HttpServiceProxyFactory$HttpServiceMethodInterceptor.invoke(HttpServiceProxyFactory.java:243) ~[spring-web-6.2.3.jar:6.2.3]
        at .springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.3.jar:6.2.3]
        at .springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.3.jar:6.2.3]
        at jdk.proxy2/jdk.proxy2.$Proxy52.question(Unknown Source) ~[na:na]

How to properly use HttpExchange interface with an object (not the Map<String, Object>)?

Share Improve this question edited yesterday jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 4 at 14:04 PatPandaPatPanda 5,17229 gold badges120 silver badges257 bronze badges 2
  • 2 That will only work if the object is send as the body so with @RequestBody. I don't think the @ModelAttribute annotation works here, but you could try but I doubt it works. Also weird to have an content-type as json but sending request parameters. – M. Deinum Commented Mar 4 at 14:16
  • there is a tutorial video that does exactly do this using @ModelAttribute, see youtube/watch?v=stGq8lnEFlM - that part starts at 6:45. it would be useful to watch the total tutorial though... i do not have any connections to the author of this video and no intention of pushing him in any way – Martin Frank Commented Mar 4 at 15:28
Add a comment  | 

2 Answers 2

Reset to default 0

Spring doesn't automatically convert the MyQueryParameters object into query parameters for the HTTP request, you can create a custom converter :

Create a Custom Converter :

@Component
public class MyQueryParametersToStringConverter implements Converter<MyQueryParameters, String> {

    @Override
    public String convert(MyQueryParameters source) {
        return "id=" + source.id() + "&name=" + source.name() + "&age=" + source.age();
    }
}

Register the Custom Converter :

Ensure that the ioc container is aware of the custom converter by registering it in your configuration :


     @Bean
     public Converter<MyQueryParameters, String> myQueryParametersToStringConverter() {
         return new MyQueryParametersToStringConverter();
     }

This should properly convert your MyQueryParameters object to query parameters.

The first option is to use MultiValueMap<String, String>, creating a converter method that manually transforms the object into a map (e.g., QueryParamConverter.convert(myQueryParameters)) and then passing this map to the interface method. The second option is to use Reflection, writing a custom argument resolver (QueryObjectArgumentResolver) that automatically extracts object fields into query parameters when the parameter is annotated with @QueryObject, eliminating the need to manually list fields or use MultiValueMap. The first approach is simpler and requires less code, while the second is more convenient when dealing with many parameters and seeking automation.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论