spring 如何在Sping Boot REST API中将null值包含到JSON响应中

knpiaxh1  于 2023-09-29  发布在  Spring
关注(0)|答案(2)|浏览(154)

我正在开发一个RESTful API。我想通过调用API获取用户详细信息。但我期望的响应不包括空值。

预期响应

{
    "id": 1,
    "username": "admin",
    "fullName": "Geeth Gamage",
    "userRole": "ADMIN",
    "empNo": null
}

实际响应

{
        "id": 1,
        "username": "admin",
        "fullName": "Geeth Gamage",
        "userRole": "ADMIN"
    }

Sping Boot rest API代码如下。为什么不包括空参数为我的回应?

@GetMapping(value = "/{userCode}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> findUser(@PathVariable String userCode)
{
    return ResponseEntity.status(HttpStatus.OK).body(userService.getUserByUserName(userCode));
}

@Override
@Transactional
public Object getUserByUserName(String username)
{
    try {
        User user = Optional.ofNullable(userRepository.findByUsername(username))
                   .orElseThrow(() -> new ObjectNotFoundException("User Not Found"));
            
            return new ModelMapper().map(user, UserDTO.class);

    } catch (ObjectNotFoundException ex) {
        log.error("Exception  :  ", ex);
        throw ex;
    } catch (Exception ex) {
        log.error("Exception  :  ", ex);
        throw ex;
    }
}

User实体类和UserDTO对象类如下

User.class

@Data
@Entity
@Table(name = "user")
public class User{
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    private Long id;
    @Column(name = "USERNAME", nullable = false, length = 64)
    private String username;
    @Column(name = "USER_ROLE", nullable = false)
    private String userRole;
    @Column(name = "EMP_NO")
    private String empNo;
}

UserDTO.class

@Data
public class  UserDTO {
    private Long id;
    private String username;
    private String fullName;
    private String userRole;
    private String empNo;
}
pbpqsu0x

pbpqsu0x1#

假设您使用的是Jackson,您可以在ObjectMapper上使用setSerializationInclusion(JsonInclude.Include)配置其全局行为。
对于您的用例,您可以将其配置为 NON_EMPTYALWAYS。更多详情请查看https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonInclude.Include.html
您也可以在类或属性级别使用相应的注解@JsonInclude来完成此操作。

6rqinv9w

6rqinv9w2#

我做的是Jao Dias提到:在项目级别设置SerializationInclusion。因此,为了让我的Rest API响应将字段显示为null(在Jackson序列化期间被省略),前两个不起作用,即yaml文件和注册bean不起作用。

spring:
        profiles: local        
         jackson.default-property-inclusion: always

甚至添加了一个配置bean

@Bean
    public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {

        return builder -> builder.serializationInclusion(JsonInclude.Include.ALWAYS);
    }

我想,因为问题是RequestMappingsocket对我来说,而不是Jackson序列化一般,我不得不做一个工作,并在Spring容器设置注册。

@Component
public class JacksonFix {
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
    

    @PostConstruct
    public void init() {
        List<HttpMessageConverter<?>> messageConverters = requestMappingHandlerAdapter.getMessageConverters();
        for (HttpMessageConverter<?> messageConverter : messageConverters) {
            if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
                MappingJackson2HttpMessageConverter m = (MappingJackson2HttpMessageConverter) messageConverter;
        m.getObjectMapper().setSerializationInclusion(JsonInclude.Include.ALWAYS);
                
            }
        }
    }

    private JacksonFix() {
        new AssertionError("instantiation of this class not allowed");
    }

    
    @Autowired
    public void setAnnotationMethodHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
        this.requestMappingHandlerAdapter  = requestMappingHandlerAdapter;
    }

相关问题