如何在Spring 3中使用注释配置RESTful控制器?

时间:2010-02-19 02:01:18

标签: java spring rest spring-mvc

我正在尝试使用RESTful 3.0创建Spring控制器。控制器用于门户应用程序的管理API。我想要执行的操作是:

  • GET / api /门户网站列出所有门户网站
  • 用于创建新门户的POST / api /门户网站
  • GET / api / portals / {id}以检索现有门户网站
  • PUT / api / portals / {id}更新现有门户网站
  • DELETE / api / portal / {id}删除现有门户网站

如下图所示注释控制器之后,我发现列出所有门户网站的操作或创建新门户网站时没有得到映射。

所以我的问题是:

  • 我是否正确注释了课程?
  • 我是否遵循了实施RESTful Web服务的正确约定?
  • 春天可能会有什么东西坏掉吗?

下面的代码摘录显示了我如何注释我的课程:

@Controller
@RequestMapping("/api/portals")
public final class PortalAPIController
{
    private final static Logger LOGGER = LoggerFactory.getLogger(PortalAPIController.class);

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String listPortals(final Model model)
    {
         PortalAPIController.LOGGER.debug("Portal API: listPortals()");
         .
         .
         return "portals";
    }

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public String createPortal(@RequestBody final MultiValueMap<String, String> portalData, final Model model)
    {
        PortalAPIController.LOGGER.debug("Portal API: createPortal()");
        .
        .
        return "portal";
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String getPortal(@PathVariable("id") final String portalId, final Model model, final HttpServletResponse response)
        throws IOException
    {
        PortalAPIController.LOGGER.debug("Portal API: getPortal()");
        .
        .
        return "portal";
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public String updatePortal(@PathVariable("id") final String portalId,
        @RequestBody final MultiValueMap<String, String> portalData, final Model model, final HttpServletResponse response)
        throws IOException
    {
        PortalAPIController.LOGGER.debug("Portal API: updatePortal()");
        .
        .
        return "portal";
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public String deletePortal(@PathVariable("id") final String portalId, final Model model, final HttpServletResponse response)
        throws IOException
    {
        PortalAPIController.LOGGER.debug("Portal API: deletePortal()");
        .
        .
        return "portal";
    }

    .
    .
}

在启动期间,我看到Spring注册了终点:

2010-02-19 01:18:41,733 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,734 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,734 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}.*] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals/{id}/] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]
2010-02-19 01:18:41,735 INFO [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] - Mapped URL path [/api/portals.*] onto handler [com.btmatthews.mars.portal.web.controller.PortalAPIController@141717f]

但是当我尝试使用cURL

调用我的API时
curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals/

curl http://localhost:8080/com.btmatthews.minerva.portal/api/portals

我收到以下错误:

2010-02-19 01:19:20,199 WARN [org.springframework.web.servlet.PageNotFound] - No mapping found for HTTP request with URI [/com.btmatthews.minerva.portal/api/portals] in DispatcherServlet with name 'portal'
2010-02-19 01:19:32,360 WARN [org.springframework.web.servlet.PageNotFound] - No mapping found for HTTP request with URI [/com.btmatthews.minerva.portal/api/portals/] in DispatcherServlet with name 'portal'

当我尝试创建时遇到同样的问题:

curl -F ...... --request POST http://localhost:8080/com.btmatthtews.minerva/api/portals

但是如果尝试对现有资源进行操作(检索,更新或删除),它就可以正常工作。

更新@axtavt的评论中提供了解决方案。我正在使用&lt; url-pattern&gt; / api / *&lt; / url-pattern&gt;在我的web.xml servlet映射中。需要将其更改为&lt; url-pattern&gt; /&lt; / url-pattern&gt;

4 个答案:

答案 0 :(得分:4)

仔细检查url-pattern中的web.xml,并将其与您的curl参数进行比较。

Here is an example我写过这篇文章引导您完成整个Spring MVC过程。

答案 1 :(得分:0)

您在curl摘录中发布的网址

http://localhost:8080/portal/api/portals

与Spring警告中的URL不匹配

/com.btmatthews.minerva.portal/api/portals

在不知道你的webapp如何设置,它的上下文路径,Spring上下文的样子等等的情况下,很难诊断,但这听起来像是我的一个重要线索。

答案 2 :(得分:0)

你犯了一些错误。

@RequestMapping(value = "/", method = RequestMethod.GET)

public String listPortals(final Model model)
{
}

这里方法必须接受一些参数Model,但是没有传递。 你必须写出内部方法。或者如果你想传递它,你必须将它作为路径变量或请求Param发送。

@RequestMapping(value = "/{id}", method = RequestMethod.GET)

public String getPortal(@PathVariable("id") 

这里正确的语法是@PathVariable(value="id")

如果这不起作用 然后试试这个:

@RequestMapping(value = "/SOMETHING", method = RequestMethod.GET)

答案 3 :(得分:0)

在Spring 3中,Rest Controller只不过是一个常规控制器(@Component),唯一的区别是Rest控制器返回JSON / XML而不是“Views”。所以我认为你在注释方面做得很好。但是,我看不到两件丢失的东西: 1-每个方法都需要有一个“产生”值(用于内容协商):    @RequestMapping(value =“/ {id}”,method = RequestMethod.GET,produce =“application / json”)

2-您需要某种类型的ObjectMapper(例如:Marshaller和Unmarshaller)才能将对象映射到JSON / XML,反之亦然。这两个应该在您的servlet配置中,而不是配置视图解析器。 这应该是它。