这是Spring 3.1中的代码示例Spring Source Blog: From XML to @Configuration我正在尝试在我的应用程序中实现(这在Spring 2.0中完成,而不是由我学习)。
@FeatureConfiguration
class MvcFeatures {
@Feature
public MvcAnnotationDriven annotationDriven(ConversionService conversionService) {
return new MvcAnnotationDriven().conversionService(conversionService)
.argumentResolvers(new CustomArgumentResolver());
}
// ...
}
但是,我无法理解 .argumentResolvers(new CustomArgumentResolver())和他们的CustomArgumentResolver看起来像吼叫。有什么意义呢?
public class CustomArgumentResolver implements WebArgumentResolver {
@Override
public Object resolveArgument(MethodParameter param, NativeWebRequest request) throws Exception {
RequestAttribute attr = param.getParameterAnnotation(RequestAttribute.class);
if (attr != null) {
return request.getAttribute(attr.value(), WebRequest.SCOPE_REQUEST);
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}
答案 0 :(得分:3)
为了添加@ GaryF的答案,并澄清一些观点,Spring 2.5引入了带注释的控制器,它取代了Spring 2.0的旧接口式控制器。这些新控制器的方法没有固定的参数 - 该方法声明了它完成工作所需的参数,仅此而已。
例如,假设一个控制器方法需要做一件事 - 一个包含数据库中对象ID的请求参数。在Spring 2.0中,您需要实现AbstractController.handleRequestInternal()
之类的内容,例如
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
String id = request.getParameter("id");
MyThing obj = getObjById(id);
//... do stuff and return ModelAndView
}
Spring 2.5让这更容易:
@RequestMapping
public ModelAndView handle(String id) {
MyThing obj = getObjById(id);
//... do stuff and return ModelAndView
}
在这里,我们只为我们需要的东西声明参数。
到目前为止一切都很好,但这是自定义WebArgumentResolver
的用武之地。我想要完全从控制器中删除getObjById
,因为也许我认为它会使代码混乱,也许它用于许多其他控制器方法。相反,我想这样做:
@RequestMapping
public ModelAndView handle(MyThing id) {
//... do stuff and return ModelAndView
}
它甚至更简单,并且只有最少的样板代码。可以使用识别WebArgumentResolver
类型的参数的app-context注册自定义MyThing
,并知道如何从请求中提取信息。 Spring调用解析器,并将结果传递给控制器方法。
自定义解析器不常用,但在适当的情况下可以非常方便。
您问题中的示例使用CustomArgumentResolver
来解析示例的自定义RequestAttribute
类。解析器提取请求属性并将它们绑定到RequestAttribute
个对象,以便它们可以声明为控制器方法参数。
答案 1 :(得分:1)
WebArgumentResolver
是一种指定如何解析MVC映射方法的参数的方法。如果您想使用自定义对象作为MVC映射方法的参数,Spring会尝试以自己的方式弄清楚如何理解它。通常这会通过绑定发生,您提交的某些http参数与对象的字段匹配,Spring会匹配它们并为您创建一个新对象。
如果您遇到的情况是提交的参数与方法参数不完全匹配,WebArgumentResolvers就会填补空白:您提供自定义逻辑,因此Spring无需弄清楚。
在您的示例中,param是一个匹配的参数。这段自定义代码首先检查参数是否具有@RequestAttribute注释。如果是,则自定义代码从该对象中提取值并将其作为http请求中的属性进行查找,并将其返回。它没有那个注释,那么该方法返回UNRESOLVED值,它只是表明这个WebArgumentResolver对这个特定参数一无所知,Spring应该尝试不同的方法(比如绑定)。