在Sping Boot 3的Kotlin中,我试图实现一个模式,在控制器中,我将接收一个RequestDto作为@RequestBody
,它实现了一个接口DtoInterface
,我将把这个dto传递给我的服务。服务的create
函数已经TypeHinted了DtoInterface
,任何实现这个接口的Dto类都可以传递到那里。
在我当前的实现中,我无法从服务访问dto的属性。
主计长
@RestController
@RequestMapping("api/v1/brands")
class BrandController (private val service: BrandService){
@PostMapping("/")
fun postCreate(@RequestBody brandCreateRequestDto: BrandCreateRequestDto): String
{
val test = service.create(brandCreateRequestDto);
return test
}
}
BrandCreateRequestDto
import com.example.api.dto.DtoInterface
data class BrandCreateRequestDto (
val name: String,
val title: String,
val description: String,
val slug: String,
val body: String,
val status: String,
):DtoInterface
DtoInterface
interface DtoInterface {}
现在从我的BrandService,我想输入hint this DtoInteface
来创建一个函数,但是这里的name
在data
对象中不可用。
品牌服务
@Service
class BrandService (){
fun create(data: DtoInterface): String {
return "Name: " + data.name
}
}
我在PHP中使用了类似的模式,并且运行得很好。我假设Kotlin中的语法是不同的,但找不到任何类似的解决方案。
短暂性脑缺血
2条答案
按热度按时间2wnc66cl1#
您的
DtoInterface
没有属性。如果您只知道一个对象实现了DtoInterface
,则无法保证该对象具有name
属性。例如,这里有一个类也实现了
DtoInterface
:必须允许将
Square(42)
传递给你的服务,因为它实现了DtoInterface
。但是在这种情况下,你会看到试图在这个服务上调用data.name
将失败。这是我们在编译时就知道的,所以编译器不允许它。通常使用接口的目的是定义一组可以在子类上保证的公共属性。如果你将
name
属性添加到DtoInterface
,任何子类都必须定义这个属性:有了这些定义,服务可以调用
data.name
属性,因为我们可以确保所有子类都有这个属性。你可以通过override
关键字看到这个属性来自一个超类型。现在,也许
name
不应该被认为是你的例子中的公共属性。如果是这样,一个替代方案是简单地将BrandCreateRequestDto
声明为你的服务方法的输入,这将解决这个问题:qnzebej02#
除了Joffrey的答案,你还可以使用Kotlin的smart cast feature: