對於同一個問題,我有兩種解決方案,但我不確定哪種解決方案最適合長期使用。@RequestBody與Spring中的HandlerMethodArgumentResolver
溶液1:
控制器是:
@RequestMapping(value = "/skill/leatherworking/curing/start", method = RequestMethod.POST)
public Response startCuring(final UserEntity userEntity, @RequestBody @Valid final CuringCreateRequest curingCreateRequest) {
final CuringResult result = curingService.cure(userEntity, recipeDefinitionCache.getDefinition(curingCreateRequest.getRecipeId()));
...
}
和域目的是:
public class CuringCreateRequest {
@Min(1)
private int recipeId;
...
}
溶液2:
控制器是:
@RequestMapping(value = "/skill/leatherworking/curing/start", method = RequestMethod.POST)
public Response startCuring(final UserEntity userEntity, @Valid final CuringCreateRequest curingCreateRequest) {
final CuringResult result = curingService.cure(userEntity, curingCreateRequest.getRecipe());
...
}
在這裏,我們也有一個HandlerMethodArgumentResolver:
public class RequestContextHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
/**
* {@inheritDoc}
*/
@Override
public boolean supportsParameter(final MethodParameter parameter) {
return parameter.getParameterType().equals(CuringCreateRequest.class);
}
/**
* {@inheritDoc}
*/
@Override
public Object resolveArgument(final MethodParameter parameter, final ModelAndViewContainer mavContainer, final NativeWebRequest webRequest,
final WebDataBinderFactory binderFactory) throws Exception {
... //Manually resolve the argument via JsonMapper and RecipeDefinitionCache. This way we can create an immutable class and that's a bonus too.
}
}
和域對象是:
public class CuringCreateRequest {
@NotNull
private RecipeDefinition recipe;
...
}
哪種方案更好地在長期使用?特別是在一箇中型或大型項目中?我更喜歡解決方案2,因爲它的清潔度和控制器的響應性較低,但並不完全確定它的優點足以滿足爲每個不同參數創建另一個類的麻煩。特別是@RequestBody可以在2秒內解決問題。
爲什麼你不能用解決方案1創建一個不可變的對象。使用直接字段訪問而不是屬性訪問和presto。您不希望爲您需要綁定的每個類都推出自己的實現,請使用該框架來獲得您的優勢。 –
@ M.Deinum主要原因爲什麼我會使用HandlerMethodArgumentResolver,因爲我可以解析解析器中的配方而不是控制器中的配方。這樣控制器甚至不應該知道recipeDefinitionCache。 (我儘量避免使用控制器。) –
使用來自Jackson的自定義(De)串行器(假設您使用該串行器)來應用該功能。此外,爲什麼控制器應該知道,您可以隨時將該行移至服務器(應該放在第一位的地方)以執行查找。 –