春天应用在kotlin中的行为怪异

问题描述 投票:1回答:1

我是一个完全陌生的Spring + Kotlin,正试图写一个简单的服务器。我想写一个可执行的示例代码,一个应用服务器接收来自客户端的请求,并将请求发送到另一个服务器,服务器将返回结果,而应用服务器将返回结果给客户端。

我把服务器绑定在localhost:9000上,当我把请求发送给 localhost:9000/music?user=whatever我先是得到了预期的结果,如下图。

[
    "Music(Genre=Rock, Mood=[Joyful, Depressed])"
]

但是,再次发送同样的请求(使用postman),我得到的结果是 [] 作为返回。我无法理解这种行为,因为我希望每次发送请求都能返回相同的结果。样本输入在控制器代码中是硬编码的,作为一个名为sampleList的变量,我的目标是改变这部分,在解决这个问题后,从客户端接收这个变量作为请求体。我的目标是改变这部分,在解决这个问题后,从客户端接收这个变量作为请求体。

谁能解释一下,为什么会出现这种意外的行为呢? 非常感谢。代码如下图所示。

package org.whatever

import org.springframework.web.bind.annotation.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

@RestController
class MusicController {

    @GetMapping("/music")
    fun retrieveMusicInfo(@RequestParam(value = "user") user: String): MutableList<String> {
        val valList = mutableListOf<String>()

        val sampleList: List<Int> = listOf(1, 2, 3, 4)
        val sampleAmplitudes = Amplitudes(sampleList)
        MusicService.create()?.genreMoodRequest(sampleAmplitudes).enqueue(object : Callback<Music> {
            override fun onFailure(call: Call<Music>, t: Throwable) { // Whatever }
            override fun onResponse(call: Call<Music>, response: Response<Music>?) {
                val data = response?.body()?.toString()
                data?.let { valList.add(it) }
            }
        })
        return valList
    }
}

服务逻辑如下。

package org.whatever

import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST

interface MusicService {
    @Headers("accept: application/json",
            "content-type: application/json")
    @POST("/")
    fun genreMoodRequest(@Body params: Amplitudes)
        : Call<Music>

    companion object {
        fun create(): MusicService {
            val retrofit = Retrofit.Builder()
                    .baseUrl("http://localhost:5000")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()

            return retrofit.create(MusicService::class.java)
        }
    }
}
spring-boot kotlin retrofit2
1个回答
2
投票

遇到的问题

翻新 enqueue() 所以它不会阻塞处理请求的Spring线程。

因此,请求的线程可以在收到retrofit客户端的响应之前完成。

解决办法

1) 使用弹簧 RestTemplate 而不是改型

2) 使用带有阻塞API的改造(不是 enqueue())

© www.soinside.com 2019 - 2024. All rights reserved.