当前位置: 首页 > 知识库问答 >
问题:

Spring

祁和通
2023-03-14

我正在使用SpringMVC5.0.8和jackson 2.9.8开发RESTAPI

如果客户端的json请求中不存在分页属性,我想对每个请求设置默认分页。

我是通过从HttpRequestEntity类构造函数创建分页对象来实现这一点的,但如果json请求中存在分页请求,那么jackson在调用HttpRequestEntity类的setter方法(setPagination(Pagination Pagination))之前,通过调用分页类的默认构造函数来创建另一个分页对象。

如果JSON请求中不存在属性,JackSon既不会创建属性对象,也不会命中属性setter方法

我也用Interceptor prepreHandle试过这个

request.setAttribute("pagination", new Pagination());

但这不会更新HttpServletRequest的主体,我必须接收该属性与Controller的参数,这应该是注释与@刚体属性。

根据我的理解,HttpMessageConverter仅将HttpServletRequest正文映射为spring注释@RequestBody。

Json请求

{
   //not sending pagination
   /*
   "pagination":{
      "offset":0,
      "limit:50
    },
    */
    "data":{
        "requestUrl":"some value"
        ...
    },
    "timeStamp":"Mon Sep 23 2019 02:15:47 GMT+0530 (India Standard Time)"
}

控制器

@RestController
@RequestMapping("/api/v1")
public class LocaldbController {

    @Autowired
    private LocaldbService localdbService;

    @PostMapping("/apidetails/filter")
    public void getAllApiDetails(@RequestBody HttpRequestEntity<ApiDetailsFilterDto> requestEntityDto) {

        System.out.println(requestEntityDto.getPagination().getLimit());
    }
}
public class HttpRequestEntity<T> {

    public Pagination pagination;
    private T data;
    private String timeStamp;

    public HttpRequestEntity() {
        this.pagination = new Pagination(); //To set Default value
    }

    public Pagination getPagination() {
        return pagination;
    }
    public T getData() {
        return data;
    }
    public String getTimeStamp() {
        return timeStamp;
    }
    public void setTimeStamp(String timeStamp) {
        this.timeStamp = timeStamp;
    }

    public void setPagination(Pagination pagination) {
        this.pagination = pagination;
    }

}
public class Pagination {

    private int offset = 0;
    private int limit = 50;

    public Pagination() {
        System.out.println("pagination");
    }

    public int getOffset() {
        return offset;
    }
    public int getLimit() {
        return limit;
    }

    public void setOffset(int offset) {
        this.offset = offset;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }
}

所以任何人都可以告诉我,如果JSON请求中没有属性,如何为属性设置默认值。

谢谢你的关注。我期待着你的答复。

共有2个答案

呼延英奕
2023-03-14

如果您想再次从分页的构造函数中创建对象,请检查setter分页方法

public void setPagination(Pagination pagination) {
If(this.pagination!=null)
this.pagination==null//contructor object set to null
        this.pagination = pagination;
    }

}

我不知道您的实际需求,为什么不创建动态分页对象呢。检查get Pagination是否为null创建分页对象。创建一个服务类并从控制器调用该服务类以获取数据,该服务类检查所有数据,如果为空,则动态创建分页对象,表示Jackson不会命中setter方法。。。也许它能帮上忙。。。

谯英彦
2023-03-14

我不知道请求反序列化背后的逻辑是什么,但是我可以建议您将新的分页()调用从构造函数移动到字段声明,因为如果发生Java反射魔法,构造函数中的逻辑可能不会被调用。

public class HttpRequestEntity<T> {

    public Pagination pagination = new Pagination();
    ...

我想指出的另一件事是,您不应该担心冗余对象的创建,因为像垃圾收集器这样的机制的存在只是为了不必担心内存管理。

编辑:
好的,我看到你顽固地检查分页是否发送。如果您需要检查这一点,您就做错了,因为默认数据应该指示默认行为(默认逻辑),并且不应该以任何方式阻止您的逻辑。

您不必担心每次都会创建默认对象,因为Java的内存管理非常有效。

但是如果您真的想检查分页是默认值还是实际上由客户端发送的,请使用装饰器模式

public class HttpRequestEntity<T> {

    public Pagination pagination = new DefaultPagination();
    ...
}

public final class DefaultPagination extends Pagination {
    public DefaultPagination() {
        super();
    }

    @Override
    public void setOffset(int offset) {
        throw new IllegalStateException("Default pagination's state change not allowed");
    }

    @Override
    public void setLimit(int limit) {
        throw new IllegalStateException("Default pagination's state change not allowed");
    }
}

然后可以检查分页是否为DefaultPagination的实例

 类似资料:
  • 问题内容: 我正在创建一些轻松的Web服务,并使用Spring-Boot创建嵌入式的tomcat容器。 要求之一就是要实现2路SSL。我一直在看HttpSecurity对象,可以使用以下方法使它仅通过SSL通道运行Web服务: 我似乎找不到一种使Web服务仅对提供有效客户端证书的应用程序可访问的方法。 我只有SSL的基本知识,因此即使是正确方向的通用指针也将不胜感激。 部署到该服务器上的服务器将具

  • 问题内容: 我在Spring领域还很陌生,我开发了一个简单的项目,该项目使用Spring 3.2.1和Hibernate 4.1.9来实现DAO。该项目可以正常工作,但是我对在此DAO的CRUD方法上使用 @Transactional Spring批注有一些疑问。 这是实现我的项目的CRUD操作的类的完整代码: 好的,正如您所看到的,使用@Transactional注释对某些方法进行了注释。 我在

  • 问题内容: 我正在使用最新的spring-data- mongodb(1.1.0.M2)和最新的Mongo驱动程序(2.9.0-RC1)。我遇到这样的情况,我有多个客户端连接到我的应用程序,并且我想在同一台Mongo服务器中为每个客户端提供自己的“模式/数据库”。如果我直接使用驱动程序,这并不是一件很难的事情: 看,容易。但是spring-data- mongodb不允许使用简单的方法来使用多个数

  • 问题内容: 一个在方法-annotated类不被异步调用-它阻塞线程。 我已经进入配置,对方法的调用来自类外部,因此应该点击代理。当我单步执行代码时,确实会碰到代理,但似乎没有在与在任务执行器中运行相关的任何类附近的任何地方。 我已经设置了断点,但是它们从未被击中。我已经调试过,可以看到建议得到应用。 该服务被定义为接口(该接口的方法带有适当的注释),实现的方法也带有注释。都没有标记。 任何想法可

  • 问题内容: 我到处都读到有关Spring如何鼓励您在代码中使用接口的信息。我没看到 您的spring xml配置中没有接口的概念。Spring的哪一部分实际上鼓励您使用接口(而不是文档)? 问题答案: 为类定义接口时,它有助于进行依赖项注入。您的Spring配置文件本身不包含任何有关接口的信息-您只需输入类的名称即可。 但是,如果您要注入另一个提供“等效”功能的类,则使用接口确实会有所帮助。 例如

  • 问题内容: 我想看看在Spring中使用一个DataSources但能够从Java代码中切换数据库的最佳方法是什么?以下是我的两个数据源,它们分别位于相同的数据库服务器但位于不同的数据库中。 我将它们绑定到各自的bean,但是我正在查看我的旧代码,用2个单独的bean来实现它非常尴尬。是否在需要时如何使用一个数据源和切换数据库方面有什么想法/想法? 问题答案: 您可以通过扩展Sp​​ring 并在

  • 问题内容: 如果我有一个下面定义的Java类,则通过依赖项注入将其插入我的Web应用程序中: 我担心线程安全。Spring框架是否不能处理一个请求正在从列表中读取而当前正在被另一个请求更新的情况?我以前在其他应用程序中使用过读/写锁,但是我之前从未考虑过这种情况。 我打算将bean作为单例使用,以便减少数据库负载。 顺便说一下,这是以下问题的跟进: Java内存存储以减少数据库负载-安全吗? 编辑

  • 问题内容: 我使用的是Spring 4,我注意到了一个奇怪的行为……如果我从普通实例方法多次调用异步方法,那么它们都将在不同的线程中调用,并在随机时间完成。但是,如果我多次从另一个异步方法中调用一个异步方法,那么它们将按顺序完成。我有这样的事情: 我正在使用默认的异步执行器。我应该换一个吗?但是,该执行程序不会重用任何线程,而是每次都启动另一个线程,因此应该没问题……这仅仅是巧合吗?但是我尝试了十