问题描述
是否有任何理由不将Controller映射为接口?
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.
我的控制器界面如下:
@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
注释添加到具体类中,那么一切都会按预期进行,但是为什么我必须在具体类中重新声明呢?
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无法将其识别为@PathVariable
明确声明它.没有它,将不会执行任何以@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带注释的控制器接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!