当前位置: 首页 > 面试题库 >

如何装饰所有HTTP请求以从标头获取值并将其添加到body参数中?

傅泉
2023-03-14
问题内容

背景
我正在使用Spring MVC创建一系列RESTful服务。当前,我具有以下控制器结构:

@RestController
@RequestMapping(path = "myEntity", produces="application/json; charset=UTF-8")
public class MyEntityController {

    @RequestMapping(path={ "", "/"} , method=RequestMethod.POST)
    public ResponseEntity<MyEntity> createMyEntity(
        @RequestBody MyEntity myEntity,
        @RequestHeader("X-Client-Name") String clientName) {
        myEntity.setClientName(clientName);
        //resto de declaración del método...
    }

    @RequestMapping(path={ "/{id}"} , method=RequestMethod.PUT)
    public ResponseEntity<MyEntity> updateMyEntity(
        @PathVariable Long id,
        @RequestBody MyEntity myEntity,
        @RequestHeader("X-Client-Name") String clientName) {
        myEntity.setClientName(clientName);
        //resto de declaración del método...
    }

    @RequestMapping(path={ "/{id}"} , method=RequestMethod.PATCH)
    public ResponseEntity<MyEntity> partialUpdateMyEntity(
        @PathVariable Long id,
        @RequestBody MyEntity myEntity,
        @RequestHeader("X-Client-Name") String clientName) {
        myEntity.setClientName(clientName);
        //resto de declaración del método...
    }
}

可以看出,这三种方法对于标头是相同的参数,@RequestHeader("X-Client-Name") String clientName并且在每种方法中都采用相同的方式:myEntity.setClientName(clientName)。我将创建类似的控制器,对于POST,PUT和PATCH操作,它们将包含类似的代码,但面向其他实体。当前,大多数实体旨在通过父类支持此字段:

public class Entity {
    protected String clientName;
    //getters y setters ...
}
public class MyEntity extends Entity {
    //...
}

注意,我使用拦截器来验证是否已根据请求设置标头。


如何避免在控制器和方法中重复相同的代码?有没有一种干净的方法可以实现这一目标,而无需代码重复?还是我注定要在将来的控制器的所有方法中重复参数和同一行代码?


问题答案:

可以使用class删除一些重复的代码org.springframework.web.bind.annotation.ModelAttribute。也就是说:

@RestController
@RequestMapping(path = "myEntity", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class MyEntityController {

    @ModelAttribute("model")
    public MyEntity populate(
            @RequestBody MyEntity myEntity,
            @RequestHeader("X-Client-Name") String clientName) {
        myEntity.setClientName(clientName);
        return myEntity;
    }

    @RequestMapping(path = {"", "/"}, method = RequestMethod.POST)
    public ResponseEntity<MyEntity> createMyEntity(
            @ModelAttribute("model") MyEntity myEntity) {
        ⋮
    }

    @RequestMapping(path = {"/{id}"}, method = RequestMethod.PUT)
    public ResponseEntity<MyEntity> updateMyEntity(
            @PathVariable Long id,
            @ModelAttribute("model") MyEntity myEntity) {
        ⋮
    }

    @RequestMapping(path = {"/{id}"}, method = RequestMethod.PATCH)
    public ResponseEntity<MyEntity> partialUpdateMyEntity(
            @PathVariable Long id,
            @ModelAttribute("model") MyEntity myEntity) {
        ⋮
    }

}

该方法populate将在每次请求到该控制器调用与注释的方法之前被调用@RequestMapping。

由于始终在每个请求上执行此方法,因此即使对于那些不使用此类数据的方法,也需要有效负载和标头(”X-Client-Name”),并且如果它们未在请求中传播,则将引发异常。您可以使用属性修改该要求。也就是说:required = false

    @ModelAttribute("model")
    public MyEntity populate(
            @RequestBody(required = false) MyEntity myEntity,
            @RequestHeader(required = false, value = "X-Client-Name") String clientName) {
        if (myEntity != null) {
            myEntity.setClientName(clientName);
        }
        return myEntity;
    }


 类似资料:
  • 问题内容: 背景 我正在使用Spring MVC创建RESTful服务。当前,我具有以下控制器结构: 如您所见,这三种方法都为标头接收相同的参数,并以相同的方式将其应用于每种方法:。我将创建类似的控制器,并且对于POST,PUT和PATCH操作将包含几乎相同的代码,但适用于其他实体。当前,大多数实体旨在通过超类来支持该领域: 另外,我使用拦截器来验证是否已为请求设置标头。 题 如何避免通过控制器类

  • 问题内容: 澄清点:将自定义标头添加到我的jQuery ajax调用中没有任何问题,我想将我的自定义标头自动添加到所有ajax调用中。 如果您看看jquery $.ajax自定义http标头问题(不是我的问题),您将看到一个很好的示例,说明如何为每个ajax调用手动实现代码。 我想为所有jQuery ajax调用覆盖beforeSend。根据jQuery文档,我可以使用jQuery.ajaxSet

  • 问题内容: 这是我的第一篇文章。 我刚刚开始学习Go和Angular,并且尝试将angular应用程序连接到go api。我已经写了这两本书,并且一直坚持找出问题的根源。我以为这是一个CORS问题,但是如果我在Angular http请求中不包含代码的标题行,它就可以正常工作。在这一点上,我只是想添加标题。授权代码尚未实现。 这两个应用程序都在本地运行,端口5000上的Go应用程序和4200端口上

  • 问题内容: 我需要获取所有Django请求标头。根据我的阅读,Django只是将所有内容与大量其他数据一起转储到变量中。获取客户端发送到我的Django应用程序的所有标头的最佳方法是什么? 我将使用它们来构建httplib请求。 问题答案: 根据文档,这 是“包含所有可用HTTP标头的标准Python词典”。如果要获取所有标头,则可以简单地遍历字典。 代码的哪一部分执行此操作取决于你的确切要求。有

  • 问题内容: 我正在尝试访问网站,但无法将收集到的“ Cookie”添加到传出的POST请求标头中。我已经能够验证它们是否存在于CookieManager中。 HtmlUnit的任何替代方法也将不胜感激。 问题答案: 我发现可以使用WebClient中的setadditionalHeader()添加标题。

  • 问题内容: 我已经开发了一个Restfull应用程序,我想添加另一个Web应用程序来使用其服务,因此我进行了以下Ajax调用: 我得到这个例外: 对象{readyState:0,状态:0,statusText:“ SyntaxError:无法执行’setRequestHeader’…-Origin: ‘不是有效的HTTP标头字段名称。”}错误DOMException:无法在’XMLHttpRequ