6

ControllerLinkBuilder.methodOn()String 以外の型でSpring を呼び出そうとしていますが、常に失敗します。Converterまた、どの種類を使用し、どこに登録すればよいかわかりません。

これが私のコントローラーです:

@RestController
@RequestMapping("/companies")
class CompanyController {

    @RequestMapping(value="/{c}", method=RequestMethod.GET)
    void getIt(@PathVariable Company c) {
        System.out.println(c);
        Link link = linkTo(methodOn(getClass()).getIt(c));
    }

}

System.out.println(c)うまくいきます。私Companyのドメイン オブジェクトは DB からフェッチされます。(私は使用していDomainClassConverterます)

しかし、他の方法は機能しません:ConverterNotFoundException: No converter found capable of converting from type @PathVariable Company to type String

私はちょうど必要Converter<Company, String>ですか?また、どこに登録すればよいですか?addFormatters(FormatterRegistry registry)のメソッド内で何かを試しましたWebMvcConfigurationSupportが、同じエラーが表示されました。しかし、結局のところ、私が何を試したのか正確にはわかりません...

4

4 に答える 4

0

Spring Hateoas でリンクをレンダリングするためのフレームワークを開発しました。このフレームワークは、注釈付きパラメーター (@PathVariableおよび@RequestParam) と任意のパラメーター タイプをサポートしています。

これらの任意の型をレンダリングするには、com.github.osvaldopina.linkbuilder.argumentresolver.ArgumentResolverインターフェースを実装する Spring Bean を作成する必要があります。

インターフェイスには 3 つのメソッドがあります。

  1. public boolean resolveFor(MethodParameter methodParameter)

ArgumentResolverを処理するために を使用できるかどうかを判断するために使用されmethodParameterます。例えば:

public boolean resolveFor(MethodParameter methodParameter) {
    return UserDefinedType.class.isAssignableFrom(methodParameter.getParameterType());
}

ArgumentResoverこれが に使用されることを定義しUserDefinedTypeます。

  1. public void augmentTemplate(UriTemplateAugmenter uriTemplateAugmenter, MethodParameter methodParameter)

メソッドに関連付けられた uriTemplate に適切なテンプレート パーツを含めるために使用されます。例えば:

@Override
public void augmentTemplate(UriTemplateAugmenter uriTemplateAugmenter, MethodParameter methodParameter) {
    uriTemplateAugmenter.addToQuery("value1");
    uriTemplateAugmenter.addToQuery("value2");

}

URI テンプレートに 2 つのクエリ パラメータ (value1 と value2) を追加します。

  1. public void setTemplateVariables(UriTemplate template, MethodParameter methodParameter, Object parameter, List<String> templatedParamNames)

テンプレート変数の値をテンプレートに設定します。例えば:

@Override
public void setTemplateVariables(UriTemplate template, MethodParameter methodParameter, Object parameter, List<String> templatedParamNames) {
    if (parameter != null && ((UserDefinedType) parameter).getValue1() != null) {
        template.set("value1", ((UserDefinedType) parameter).getValue1());
    }
    else {
        template.set("value1", "null-value");
    }

    if (parameter != null && ((UserDefinedType) parameter).getValue2() != null) {
        template.set("value2", ((UserDefinedType) parameter).getValue2());
    }
    else {
        template.set("value2", "null-value");
    }
}

インスタンスを取得し、UserDefinedTypeそれを使用して、メソッドで定義されたテンプレート変数 value1 および value2 を設定しますaugmentTemplate

ArgumentResolver完全な例は次のとおりです。

@Component
public class UserDefinedTypeArgumentResolver implements ArgumentResolver {

    @Override
    public boolean resolveFor(MethodParameter methodParameter) {
        return UserDefinedType.class.isAssignableFrom(methodParameter.getParameterType());
    }

    @Override
    public void augmentTemplate(UriTemplateAugmenter uriTemplateAugmenter, MethodParameter methodParameter) {
        uriTemplateAugmenter.addToQuery("value1");
        uriTemplateAugmenter.addToQuery("value2");

    }

    @Override
    public void setTemplateVariables(UriTemplate template, MethodParameter methodParameter, Object parameter, List<String> templatedParamNames) {
        if (parameter != null && ((UserDefinedType) parameter).getValue1() != null) {
            template.set("value1", ((UserDefinedType) parameter).getValue1());
        }
        else {
            template.set("value1", "null-value");
        }

        if (parameter != null && ((UserDefinedType) parameter).getValue2() != null) {
            template.set("value2", ((UserDefinedType) parameter).getValue2());
        }
        else {
            template.set("value2", "null-value");
        }
    }
}

および次のリンク ビルダーの場合:

   linksBuilder.link()
            .withRel("user-type")
            .fromControllerCall(RootRestController.class)
            .queryParameterForUserDefinedType(new UserDefinedType("v1", "v2"));

次のメソッドに:

@RequestMapping("/user-defined-type")
@EnableSelfFromCurrentCall
public void queryParameterForUserDefinedType(UserDefinedType userDefinedType) {

}

次のリンクが生成されます。

{
    ...
    "_links": {
        "user-type": {
        "href": "http://localhost:8080/user-defined-type?value1=v1&value2=v2"
    }
    ...
}

}

于 2016-06-08T22:42:08.743 に答える
0

スプリング ブートの完全な構成。Franco Gotussoの回答と同じように、詳細を提供するだけです。```

/** * この設定ファイルは、Spring Hateoas のバグを修正するためのものです。※ https://github.com/spring-projects/spring-hateoas/issues/118をご確認ください。*/

@Component public class MvcConfig extends WebMvcConfigurerAdapter {

@Autowired
private ApplicationContext applicationContext;

@Override
public void addFormatters(final FormatterRegistry registry) {
    super.addFormatters(registry);

    try {
        Class<?> clazz = Class.forName("org.springframework.hateoas.mvc."
                + "AnnotatedParametersParameterAccessor$BoundMethodParameter");
        Field field = clazz.getDeclaredField("CONVERSION_SERVICE");
        field.setAccessible(true);
        DefaultFormattingConversionService service =
                (DefaultFormattingConversionService) field.get(null);
        for (Formatter<?> formatter : applicationContext
                .getBeansOfType(Formatter.class).values()) {
            service.addFormatter(formatter);
        }
        for (Converter<?, ?> converter : applicationContext
                .getBeansOfType(Converter.class).values()) {
            service.addConverter(converter);
        }
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

}

```

于 2017-08-31T13:12:19.353 に答える