jackson 用作控制器方法返回类型的Micronaut的Page序列化时不带Page属性

f5emj3cl  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(126)

我尝试使用Micronaut 3.7.9和micronaut-serde-Jackson实现一个简单的分页API,我遇到了如何序列化响应的问题,因为不包括Page属性。我的控制器方法返回类型是io. micronaut. data. model. Page。
而不是得到这样的响应(用micronaut-openapi的swagger生成的示例响应):

{
  "content": [
  {
    "id": 0,
    "name": "Group1"
  }
  ],
  "pageable": {
    "orderBy": [
      {
        "ignoreCase": true,
        "direction": "ASC",
        "property": "string",
        "ascending": true
      }
    ],
    "number": 0,
    "size": 0,
    "sort": {
      "orderBy": [
        {
          "ignoreCase": true,
          "direction": "ASC",
          "property": "string",
          "ascending": true
        }
      ]
    },
    "sorted": true
  },
  "pageNumber": 0,
  "offset": 0,
  "size": 0,
  "empty": true,
  "numberOfElements": 0,
  "totalSize": 0,
  "totalPages": 0
}

字符串
我只是从pageable的content数组中获取项目的普通数组:

[
  {
    "id": 0,
    "name": "Group1"
  }
]


我已经将这个问题追溯到io.micronaut.serde.support.DefaultSerdeRegistry的findSerializer方法,该方法为Page示例返回io.micronaut.serde.support.serializers.IterableSerializer(这是可以理解的,因为Page有效地实现了Iterable)。
我想知道是否有一种方法可以配置Serde序列化Pageable及其示例字段(size,totalPages等),而不是创建一个不继承Iterable的自定义Page或注册自己的Serializer示例,特别是对于io.micronaut.data.model.Page?
[编辑]相关职业:

页面:

https://github.com/micronaut-projects/micronaut-data/blob/master/data-model/src/main/java/io/micronaut/data/model/Page.java

仓库:

package org.example.repository;

import io.micronaut.data.annotation.Repository;
import io.micronaut.data.repository.PageableRepository;
import org.example.model.Group;

@Repository
public interface GroupRepository extends PageableRepository<Group, Long> {
}

服务:

package org.example.service;

import io.micronaut.data.model.Page;
import io.micronaut.data.model.Pageable;
import jakarta.inject.Singleton;
import lombok.RequiredArgsConstructor;
import org.example.dto.GroupDto;
import org.example.repository.GroupRepository;

@Singleton
@RequiredArgsConstructor
public class GroupService {
    private final GroupRepository groupRepository;

    public Page<GroupDto> findAllGroups(Pageable pageable) {
        return groupRepository.findAll(pageable).map(GroupDto::from);
    }
}

控制器:

package org.example.controller;

import io.micronaut.data.model.Page;
import io.micronaut.data.model.Pageable;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import org.example.dto.GroupDto;
import org.example.service.GroupService;

@Controller("/groups")
@RequiredArgsConstructor
public class GroupController {
    private final GroupService groupService;

    @Get
    public Page<GroupDto> findAllGroups(@Parameter(hidden = true) Pageable pageable) {
        return groupService.findAllGroups(pageable);
    }
}

DTO

package org.example.dto;

import io.micronaut.serde.annotation.Serdeable;
import org.example.model.Group;

@Serdeable
public record GroupDto(Long id, String name, int version) {
    public static GroupDto from(Group group) {
        return new GroupDto(group.getId(), group.getName(), group.getVersion());
    }
}

实体:

package org.example.model;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Table(name = "_group")
@NoArgsConstructor @Getter @Setter
public class Group {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    private String name;
    @Version
    private int version;
}

7eumitmz

7eumitmz1#

您可以使用自定义序列化程序:

@Prototype
final class DefaultPageSerializer implements Serializer<DefaultPage<Object>> {

    @Override
    public void serialize(Encoder encoder, EncoderContext context, Argument<? extends DefaultPage<Object>> type, DefaultPage<Object> page) throws IOException {
        Encoder e = encoder.encodeObject(type);

        e.encodeKey("content");
        Argument<List<Object>> contentType = Argument.listOf((Argument<Object>) type.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT));
        context.findSerializer(contentType)
            .createSpecific(context, contentType)
            .serialize(e, context, contentType, page.getContent());

        e.encodeKey("pageable");
        Argument<Pageable> pageable = Argument.of(Pageable.class);
        context.findSerializer(pageable)
            .createSpecific(context, pageable)
            .serialize(e, context, pageable, page.getPageable());

        e.encodeKey("totalSize");
        e.encodeLong(page.getTotalSize());

        e.finishStructure();
    }
}

字符串
这应在Micronaut 4中修复。

相关问题