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

如何修饰所有从标头获取值并将其添加到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);
        //rest of method declaration...
    }

    @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);
        //rest of method declaration...
    }

    @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);
        //rest of method declaration...
    }
}

如您所见,这三种方法都为标头接收相同的参数,@RequestHeader("X-Client-Name") String clientName并以相同的方式将其应用于每种方法:myEntity.setClientName(clientName)。我将创建类似的控制器,并且对于POST,PUT和PATCH操作将包含几乎相同的代码,但适用于其他实体。当前,大多数实体旨在通过超类来支持该领域:

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

另外,我使用拦截器来验证是否已为请求设置标头。

如何避免通过控制器类和方法重复相同的代码?有没有一种干净的方法来实现它?还是应该声明该变量并在各处重复这些行?


问题答案:

我在西班牙语站点(我也发布了这个问题)上得到了一个有趣的答案,并基于该答案可以生成适合此需求的我的答案。这是我对SOeshttp://codingdict.com/questions/144870。

基于@PaulVargas的回答http://codingdict.com/questions/144870想法(在控制器中使用继承),我为这种情况提供了更强大的解决方案。该设计包括两个部分:

  1. 为具有这种行为的控制器定义一个超类。BaseController<E extends Entity>之所以称为此类,Entity是因为几乎是我所有实体的超类(在问题中解释)。在此类中,我将检索@RequestBody E entityparameter 的值并将其分配给@ModelAttribute@PaulVargas说明的参数。泛型功能在这里有很大帮助。

  2. 我的控制器将延长BaseController<ProperEntity>哪里ProperEntity是合适的实体类,我需要与控制器来处理。然后,在方法中,仅注入the (如果需要),而不是注入@RequestBody@RequestHeader参数@ModelAttribute

阿奎斯艺术博物馆的描述:

//1.
public abstract class BaseController<E extends Entity> {

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



//2.
@RestController
@RequestMapping(path = "myEntity", produces="application/json; charset=UTF-8")
public class MyEntityController extends BaseController<MyEntity> {

    @RequestMapping(path={ "", "/"} , method=RequestMethod.POST)
    public ResponseEntity<MyEntity> createMyEntity(
        @ModelAttribute("entity") MyEntity myEntity) {
        //rest of method declaration...
    }

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

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

这样,我不需要在每个方法和控制器中重写这些代码行,就可以实现我所要求的。



 类似资料:
  • 问题内容: 背景 我正在使用Spring MVC创建一系列RESTful服务。当前,我具有以下控制器结构: 可以看出,这三种方法对于标头是相同的参数,并且在每种方法中都采用相同的方式:。我将创建类似的控制器,对于POST,PUT和PATCH操作,它们将包含类似的代码,但面向其他实体。当前,大多数实体旨在通过父类支持此字段: 注意,我使用拦截器来验证是否已根据请求设置标头。 题 如何避免在控制器和方

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

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

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

  • 问题内容: 我将这个拦截器添加到我的OkHttp客户端中: 如何在拦截器中添加标题以进行请求? 我尝试了这个,但是我犯错了,创建新请求时我丢失了请求: 请注意,我知道我可以在创建请求时添加标头,如下所示: 但这不符合我的需求。我在拦截器中需要它。 问题答案: 最后,我以这种方式添加了标题: