本文介绍了具有@PathVariable的Spring MVC带注释的控制器接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有任何理由不将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(),而不是最初声明@RequestMappingGoalService.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带注释的控制器接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-29 04:57