我正在开发 RESTful API。我想通过调用API来获取用户详细信息。但我的预期响应不包含空值。
预期回应
{
"id": 1,
"username": "admin",
"fullName": "Geeth Gamage",
"userRole": "ADMIN",
"empNo": null
}
实际反应
{
"id": 1,
"username": "admin",
"fullName": "Geeth Gamage",
"userRole": "ADMIN"
}
我的 Spring 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
对象类如下
用户.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;
}
假设您使用的是 Jackson,您可以使用 setSerializationInclusion(JsonInclude.Include)
上的
ObjectMapper
配置其 global行为。
对于您的用例,您可以将其配置为 NON_EMPTY 或 ALWAYS。有关更多详细信息,请查看https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonInclude.Include.html。
您还可以使用相应的注释在类或属性级别执行此操作
@JsonInclude
。
我所做的是 Jao Dias 提到的:在项目级别设置 SerializationInclusion。因此,为了让我的 Rest API 响应将字段显示为空(在杰克逊序列化期间被省略),前两个不起作用,即 yaml 文件和注册 bean 不起作用。
spring:
profiles: local
jackson.default-property-inclusion: always
甚至添加了一个配置bean
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> builder.serializationInclusion(JsonInclude.Include.ALWAYS);
}
我想,由于对我来说问题是 RequestMappingHandler 而不是 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;
}