[SPRING] @PathVariable DomainObject에서 String으로 변환 하시겠습니까? (ControllerLinkBuilder.methodOn 사용)
SPRING@PathVariable DomainObject에서 String으로 변환 하시겠습니까? (ControllerLinkBuilder.methodOn 사용)
Spring의 ControllerLinkBuilder.methodOn ()을 String이 아닌 타입으로 호출하려고하는데, 항상 실패합니다. 그리고 어떤 종류의 변환기를 사용할 지, 어디에 등록 할 지 모르겠습니다.
내 컨트롤러는 다음과 같습니다.
@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 Domain 객체가 DB에서 가져옵니다. (나는 DomainClassConverter를 사용하고있다)
하지만 다른 방법으로는 작동하지 않습니다 : ConverterNotFoundException : 형식을 변환 할 수있는 변환기가 없습니다. @PathVariable Company에서 String을 입력하십시오.
Converter
해결법
-
==============================
1.나는 같은 문제가 있었다. 그것은 버그 다. 모든 컨트롤러에서 복사하여 붙여 넣기를 원하지 않으면 WebMvcConfigurationSupport에서 이와 같은 것을 시도 할 수 있습니다. 그것은 나를 위해 작동합니다.
나는 같은 문제가 있었다. 그것은 버그 다. 모든 컨트롤러에서 복사하여 붙여 넣기를 원하지 않으면 WebMvcConfigurationSupport에서 이와 같은 것을 시도 할 수 있습니다. 그것은 나를 위해 작동합니다.
@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 (Converter<?, ?> converter : beanFactory.getBeansOfType(Converter.class).values()) { service.addConverter(converter); } } catch (Exception ex) { throw new RuntimeException(ex); } }
-
==============================
2."해결책"을 찾았습니다. 그것은 봄 학급으로부터 많은 복사 & 붙이기를 요구합니다, 그러나 적어도 작동합니다!
"해결책"을 찾았습니다. 그것은 봄 학급으로부터 많은 복사 & 붙이기를 요구합니다, 그러나 적어도 작동합니다!
기본적으로 org.springframework.hateoas.mvc.AnnotatedParametersParameterAccessor를 복사하고 두 줄을 변경해야했습니다.
class AnnotatedParametersParameterAccessor { ... static class BoundMethodParameter { // OLD: (with this one you can't call addConverter()) // private static final ConversionService CONVERSION_SERVICE = new DefaultFormattingConversionService(); // NEW: private static final FormattingConversionService CONVERSION_SERVICE = new DefaultFormattingConversionService(); ... public BoundMethodParameter(MethodParameter parameter, Object value, AnnotationAttribute attribute) { ... // ADD: CONVERSION_SERVICE.addConverter(new MyNewConverter()); } ... }
이 클래스는 ControllerLinkBuilderFactory에 의해 사용됩니다. 그래서 나는 그것도 복사 & 붙여 넣기했다.
그리고이 하나는 ControllerLinkBuilder에서 사용합니다. 복사하여 붙여 넣기.
내 변환기 그냥 myDomainObject.getId () 않습니다. toString () :
public class MyNewConverter implements Converter<Company, String> { @Override public String convert(Company source) { return source.getId().toString(); } }
이제 컨트롤러 안의 복사 & 붙여 넣기 ControllerLinkBuilder를 사용할 수 있으며 예상대로 작동합니다!
-
==============================
3.Spring hateoas에서 링크를 렌더링하는 프레임 워크를 개발했으며 주석 매개 변수 (@PathVariable 및 @RequestParam) 및 임의의 매개 변수 유형을 지원합니다.
Spring hateoas에서 링크를 렌더링하는 프레임 워크를 개발했으며 주석 매개 변수 (@PathVariable 및 @RequestParam) 및 임의의 매개 변수 유형을 지원합니다.
이러한 임의의 타입을 렌더링하기 위해서는 com.github.osvaldopina.linkbuilder.argumentresolver.ArgumentResolver 인터페이스를 구현하는 스프링 빈을 생성해야한다.
인터페이스에는 3 가지 방법이 있습니다.
ArgumentResolver를 사용하여 methodParameter를 처리 할 수 있는지 여부를 확인하는 데 사용됩니다. 예 :
public boolean resolveFor(MethodParameter methodParameter) { return UserDefinedType.class.isAssignableFrom(methodParameter.getParameterType()); }
이 ArgumentResover가 UserDefinedType에 사용되도록 정의합니다.
메소드와 연관된 uriTemplate에 적절한 템플릿 부분을 포함시키는 데 사용됩니다. 예 :
@Override public void augmentTemplate(UriTemplateAugmenter uriTemplateAugmenter, MethodParameter methodParameter) { uriTemplateAugmenter.addToQuery("value1"); uriTemplateAugmenter.addToQuery("value2"); }
uri 템플리트에 두 개의 조회 매개 변수 (value1 및 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"); } }
UserDefinedType 인스턴스를 가져오고이를 사용하여 augmentTemplate 메서드에 정의 된 템플릿 변수 value1 및 value2를 설정합니다.
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" } ... }
}
-
==============================
4.봄 부팅에 전체 구성. 프랑코 고투소 (Franco Gotusso)의 답변과 마찬가지로 자세한 내용을 제공합니다. ```
봄 부팅에 전체 구성. 프랑코 고투소 (Franco Gotusso)의 답변과 마찬가지로 자세한 내용을 제공합니다. ```
/ ** *이 설정 파일은 Spring Hateoas의 버그를 수정합니다. * https://github.com/spring-projects/spring-hateoas/issues/118을 확인하십시오. * /
@구성 요소 공용 클래스 MvcConfig는 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); } }
}
```
from https://stackoverflow.com/questions/22240155/converter-from-pathvariable-domainobject-to-string-using-controllerlinkbuilde by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 컨텍스트 : annotation-config가 @AutoWired의 대안입니까? (0) | 2019.05.08 |
---|---|
[SPRING] 다중 부품 구성이 제공되지 않아 부품을 처리 할 수 없음 (0) | 2019.05.08 |
[SPRING] Java / Spring에서 누락 된 변환 값을 정상적으로 처리하는 방법은 무엇입니까? (0) | 2019.05.08 |
[SPRING] java.net.MalformedURLException : 알 수없는 프로토콜 : classpath (0) | 2019.05.08 |
[SPRING] 문제 - java.lang.ClassNotFoundException : org.springframework.web.servlet.DispatcherServlet (0) | 2019.05.08 |