我有一个控制器,它可以根据id
是否为null来查找一个或多个资源。
@GetMapping(value = "/teste")
@ResponseStatus(value = HttpStatus.OK)
public ResponseEntity<?> find(Optional<ZonaIdDTO> id) {
if (id.isPresent()) {
return new ResponseEntity<>(
this.zonaMapper.toZonaRetrievalDTO(this.zonaService.findById(id.get())),
HttpStatus.OK
);
}
return new ResponseEntity<>(
this.zonaService
.findAll()
.stream()
.map(this.zonaMapper::toZonaRetrievalDTO)
.collect(Collectors.toSet()),
HttpStatus.OK
);
}
问题是条件id.isPresent()
总是被赋值为false
,即使我没有将id
传递给控制器,在这种情况下,id
对象字段被初始化为null
,但是我希望对象本身是null
,我该怎么办?
EDIT:非常清楚地说,我想知道为什么当我在没有任何参数的情况下发出请求时,参数id
不是null
,即使使用ZonaIdDTO
代替Optional<ZonaIdDTO>
也不起作用,而是将id
的所有字段都设置为null
。
例如:
// `id` should be null here
GET localhost:8080/teste
// `id` shouldn't be null here
GET localhost:8080/teste?a=1&b=2&c=3
5条答案
按热度按时间fdbelqdn1#
正如您在注解中所述,id应该是一个请求参数,并且应该是可选的(可以省略)。
Spring需要注解@RequestParam来将id作为请求参数处理,并将其与其他类型的方法参数(路径变量)区分开来。
请检查:baeldung.com/spring-requestparam-vs-pathvariable
属性'required'是用来区分强制参数和可选参数的。请注意命名也很重要。如果请求参数是abc,那么方法参数也必须是abc(至少在默认情况下,可以使用属性'name'覆盖它)。
eqfvzcg82#
java中的可选项不能为空。它必须总是非空的,如果没有数据,
id.isPresent()
将为假。如果不需要对象
id
为空,则需要将函数签名保留为ldfqzlk83#
只需将该参数作为可选参数发送即可。
是的,在控制器层实现逻辑是不好的做法,只需要编写一个服务类并在这个控制器中调用服务类方法。
ndasle7k4#
这是一个不好的做法。你应该分离你的服务,并且在这一步你不应该有一个可选的。你可以使用可选的提取数据从你的数据库,因为你不确定是否有你所期望的,但与你的客户端,你应该尊重一些合同,只是返回一个异常4xx,如果客户端不尊重合同(Http 400坏请求)。
你的合同应该是
GET /示例:提取所有示例对象
获取/示例/{id}:提取ID由{id}定义的一个示例对象
在你的开发中尽量避免〈?〉是可读的.你不应该为相同的web服务使用不同的对象
ars1skjm5#
您的控制器存在设计问题,上面的答案为您提供了解决方法。您试图在应用程序中强制执行与REST架构工作方式不兼容的行为。
1.首先,您的参数应该只是一个DTO,以帮助您将对象解析为
json
1.您可以删除方法上的
@ResponseStatus(value = HttpStatus.OK)
,因为您已经返回了OK状态1.缺省情况下,布尔值始终返回false
1.只需使用
ZonaIdDTO
作为参数