【发布时间】:2014-07-15 13:04:31
【问题描述】:
我的 Spring MVC Web 应用程序中有许多控制器,并且有一个参数 mandatoryParam 假设它必须存在于对 Web 应用程序的所有请求中。
现在我想让该参数值可用于我的 web 层和服务层中的所有方法。我怎样才能有效地处理这种情况?
目前我正在以这种方式处理它:
【问题讨论】:
标签: spring spring-mvc http-request-parameters
我的 Spring MVC Web 应用程序中有许多控制器,并且有一个参数 mandatoryParam 假设它必须存在于对 Web 应用程序的所有请求中。
现在我想让该参数值可用于我的 web 层和服务层中的所有方法。我怎样才能有效地处理这种情况?
目前我正在以这种方式处理它:
【问题讨论】:
标签: spring spring-mvc http-request-parameters
@ControllerAdvice("net.myproject.mypackage")
public class MyControllerAdvice {
@ModelAttribute
public void myMethod(@RequestParam String mandatoryParam) {
// Use your mandatoryParam
}
}
myMethod() 将针对net.myproject.mypackage 包中任何控制器的每个请求调用。 (在 Spring 4.0 之前,您无法定义包。@ControllerAdvice 应用于所有控制器)。
有关@ModelAttribute 方法的更多详细信息,请参阅Spring Reference。
【讨论】:
感谢 Alexey 带路。
他的解决办法是:
我想添加一个警告和一个更完整的例子:
警告:如果没有为 @ModelAttribute 注释提供名称,请参阅 JavaDoc for ModelAttribute.name()(最好不要使代码混乱):
默认模型属性名称是从声明的 属性类型(即方法参数类型或方法返回类型), 基于非限定类名: 例如类“mypackage.OrderAddress”的“orderAddress”, 或“List
”的“orderAddressList”。
完整的例子:
@ControllerAdvice
public class ParentInjector {
@ModelAttribute
public void injectParent(@PathVariable long parentId, Model model) {
model.addAttribute("parentDTO", new ParentDTO(parentId, "A faked parent"));
}
}
@RestController
@RequestMapping("/api/parents/{parentId:[0-9]+}/childs")
public class ChildResource {
@GetMapping("/{childId:[0-9]+}")
public ChildDTO getOne(@ModelAttribute ParentDTO parent, long childId) {
return new ChildDTO(parent, childId, "A faked child");
}
}
为了继续警告,请求声明参数“@ModelAttribute ParentDTO parent”:模型属性的名称不是变量名(“parent”),也不是原始的“parentId”,而是带有 first 的类名字母小写:“parentDTO”,所以我们必须小心使用 model.addAttribute("parentDTO"...)
编辑:一个更简单、不易出错且更完整的示例:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RestController
public @interface ProjectDependantRestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
*
* @return the suggested component name, if any
*/
String value() default "";
}
@ControllerAdvice(annotations = ParentDependantRestController.class)
public class ParentInjector {
@ModelAttribute
public ParentDTO injectParent(@PathVariable long parentId) {
return new ParentDTO(parentId, "A faked parent");
}
}
@ParentDependantRestController
@RequestMapping("/api/parents/{parentId:[0-9]+}/childs")
public class ChildResource {
@GetMapping("/{childId:[0-9]+}")
public ChildDTO getOne(@ModelAttribute ParentDTO parent, long childId) {
return new ChildDTO(parent, childId, "A faked child");
}
}
【讨论】: