在 Spring MVC 中创建新资源的 RESTful 方法到底是如何工作的?

How exactly works this RESTful method that create a new resource in Spring MVC?

我正在学习 Spring 核心认证,我对要求更改此方法的练习有以下疑问:

/**
 * Adds a Beneficiary with the given name to the Account with the given id,
 * setting its URL as the Location header on the response. 
 */
// TODO 11: Complete this method. Add annotations to respond to a
//          POST /accounts/{accountId}/beneficiaries containing a beneficiary name
//          with a 201 Created status
@RequestMapping(value = "/accounts/{accountId}/beneficiaries", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void addBeneficiary(
                           long accountId, 
                           String beneficiaryName,
                           HttpServletRequest request, 
                           HttpServletResponse response) {
    accountManager.addBeneficiary(accountId, beneficiaryName);
    //  TODO 12: Set the Location header on the Response to the location of the created beneficiary.
    //  Note the existing entityWithLocation method below.
}

根据前面代码片段中显示的 TODO 转换为 RESTfull 方法。

这是解决方案,但我在理解它的具体工作原理时遇到了一些问题:

/**
 * Adds a Beneficiary with the given name to the Account with the given id,
 * setting its URL as the Location header on the response.
 */
@RequestMapping(value = "/accounts/{accountId}/beneficiaries", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public HttpEntity<String> addBeneficiary(
        @PathVariable("accountId") long accountId,
        @RequestBody String beneficiaryName,
        @Value("#{request.requestURL}") StringBuffer url) {
    accountManager.addBeneficiary(accountId, beneficiaryName);
    return entityWithLocation(url, beneficiaryName);
}

所以 TODO 11 问我以下事情:添加注释以响应 POST /accounts/{accountId}/beneficiary 包含具有 201 创建状态 的受益人姓名。

所以我认为建议的解决方案是这样工作的:

  1. 使用@RequestMapping处理**POSTHttp请求**到/accounts/{accountId}/ beneficiaries URL(在 REST 风格中表示资源,是否正确?)

    @RequestMapping(value = "/accounts/{accountId}/beneficiaries", method = RequestMethod.POST)
    

    其中 {accountId} 是一个路径变量。因此,例如,此方法处理 URL,如“/accounts/123/beneficiary”,其中 123 值存储到名为的变量中accountId 然后我可以在我的代码中使用,实际上通过 @PathVariable 注释我检索了我用作我的输入参数的值 = 48=]addBeneficiary() 方法。

    @ResponseStatus(HttpStatus.CREATED) 注释将响应状态设置为 201 表示新资源已正确创建。

好的,现在我主要的疑惑有以下几点:

1) addBeneficiary() 方法输入参数之一是:

@RequestBody String beneficiaryName

我认为它从 HttpRequest 中提取了 String beneficiaryName,对吗?但是,如果它以这种方式工作,调用者(发送 HttpRequest 的人)如何将此参数放入 Http 请求中?

2) 原始方法(改成练习题的方法)有这2个输入参数:HttpServletRequest requestHttpServletResponse response 我认为它代表了由老式 Servlet 应用程序处理的 HttpRequestHttpResponse

这些参数被这个参数替换:

@Value("#{request.requestURL}") StringBuffer url

我认为它检索了生成 HttpRequest 的 URL。对吗?

做同样的事情吗?:

HttpRequest request.getRequestURL();

这里是您问题的答案。

  1. 调用方(发送 HttpRequest 的人)如何将此参数放入 Http Request?

调用者可以触发 ajax 请求,将 JSON 传递给控制器​​。这是发送将使用@RequestBody 注释提取的数据的方式之一。当调用者使用 JSON 数据执行 ajax post 时,Spring 将使用转换器进行转换并将其传递给您的方法。您的类路径中需要有 JACKSON 罐子。

  1. @Value("#{request.requestURL}") StringBuffer url。这与 request.getRequestURL() 相同。 Spring 正在使用 SPEL 从对象中获取数据。 SPEL 的使用方式与此类似,例如从使用 spring 注入的 Properties 对象中获取特定的 属性。