Spring & Jackson (REST): изменить тело запроса, прежде чем обращаться к контроллеру: добавить значения по умолчанию в свойства, если свойства отсутствуют в json rq - PullRequest
0 голосов
/ 22 сентября 2019

Я разрабатываю Rest Apis, используя Spring mvc 5.0.8 и Джексон 2.9.8

Я хочу установить нумерацию страниц по умолчанию для каждого запроса, если свойство пагинацииотсутствует в запросе json клиента.

Я достигаю этого, создавая Pagination объект из HttpRequestEntity конструктора класса, но если запрос pagination присутствует в запросе json, то Джексон создание еще одного Пагинация объекта путем вызова конструктора по умолчанию класса Пагинация перед вызовом метода сеттера ( setPagination (Pagination pagination) ) из HttpRequestEntity class.

JackSon не создаст объект свойства и не ударит метод установки свойства, если свойство не присутствует в JSON запрос

Я также попробовал это, используя Interceptor prepreHandle

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

Но это не обновит тело HttpServletRequest , я должен повторноceive это свойство с контроллером параметр, который должен быть аннотирован с @RequestAttribute.

Согласно моему пониманию HttpMessageConverter только карты HttpServletRequest корпус с пружинной аннотацией @ RequestBody .

Json Request

{
   //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 ]

0 голосов
/ 23 сентября 2019

Если вы хотите снова создать объект из конструктора из пагинации, проверьте метод пагинации сеттера

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

}

Я не знаю ваших реальных требований, почему бы не создать объект пагинации на лету.Проверьте, что значение get Pagination равно null, создайте объект нумерации страниц.Создайте класс обслуживания и вызовите класс обслуживания из контроллера, чтобы получить ваши данные. Этот класс обслуживания проверит все данные, соответственно, создайте объект нумерации страниц на лету, если он имеет нулевое значение, если Джексон не ударит метод установки ... Может быть, это может помочь...

0 голосов
/ 22 сентября 2019

Я точно не знаю, какова логика десериализации запросов, но я могу предположить, что вы перенесли новый вызов Pagination () из конструктора в объявление поля, так как логика из конструктора может не вызываться, если какая-то 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");
    }
}

Затем вы можете проверить, является ли разбиение на страницы instanceOf DefaultPagination

...