问题描述
是否有任何理由不将控制器映射为接口?
Is there any reason not to map Controllers as interfaces?
在我看到的所有关于控制器的例子和问题中,都是具体的类.是否有一个原因?我想将请求映射与实现分开.但是,当我尝试将 @PathVariable
作为我的具体类中的参数时,我碰壁了.
In all the examples and questions I see surrounding controllers, all are concrete classes. Is there a reason for this? I would like to separate the request mappings from the implementation. I hit a wall though when I tried to get a @PathVariable
as a parameter in my concrete class.
我的控制器界面如下所示:
My Controller interface looks like this:
@Controller
@RequestMapping("/services/goal/")
public interface GoalService {
@RequestMapping("options/")
@ResponseBody
Map<String, Long> getGoals();
@RequestMapping(value = "{id}/", method = RequestMethod.DELETE)
@ResponseBody
void removeGoal(@PathVariable String id);
}
和实现类:
@Component
public class GoalServiceImpl implements GoalService {
/* init code */
public Map<String, Long> getGoals() {
/* method code */
return map;
}
public void removeGoal(String id) {
Goal goal = goalDao.findByPrimaryKey(Long.parseLong(id));
goalDao.remove(goal);
}
}
getGoals()
方法效果很好;removeGoal(String id)
抛出异常
The getGoals()
method works great; the removeGoal(String id)
throws an exception
ExceptionHandlerExceptionResolver - Resolving exception from handler [public void
todo.webapp.controllers.services.GoalServiceImpl.removeGoal(java.lang.String)]:
org.springframework.web.bind.MissingServletRequestParameterException: Required
String parameter 'id' is not present
如果我将 @PathVariable
注释添加到具体类,一切都按预期工作,但为什么我必须在具体类中重新声明它?它不应该由带有 @Controller
注释的任何东西处理吗?
If I add the @PathVariable
annotation to the concrete class everything works as expected, but why should i have to re-declare this in the concrete class? Shouldn't it be handled by whatever has the @Controller
annotation?
推荐答案
显然,当一个请求模式通过@RequestMapping
注解映射到一个方法时,它被映射到了具体的方法实现.因此,匹配声明的请求将直接调用 GoalServiceImpl.removeGoal()
而不是最初声明 @RequestMapping
的方法,即 GoalService.removeGoal()
代码>.
Apparently, when a request pattern is mapped to a method via the @RequestMapping
annotation, it is mapped to to the concrete method implementation. So a request that matches the declaration will invoke GoalServiceImpl.removeGoal()
directly rather than the method that originally declared the @RequestMapping
ie GoalService.removeGoal()
.
由于接口、接口方法或接口方法参数上的注解不会延续到实现中,因此 Spring MVC 无法将其识别为 @PathVariablecode> 除非实现类明确声明它.没有它,任何针对
@PathVariable
参数的 AOP 建议都不会被执行.
Since an annotation on an interface, interface method, or interface method parameter does not carry over to the implementation there is no way for Spring MVC to recognize this as a @PathVariable
unless the implementing class declares it explicitly. Without it, any AOP advice that targets @PathVariable
parameters will not be executed.
这篇关于带有@PathVariable 的 Spring MVC 注释控制器接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!