spring kotlin 中的应用程序行为异常
spring application in kotlin behaving wierdly
我是 Spring + Kotlin 的新手,我正在尝试编写一个简单的服务器。我正在尝试编写一个应用程序服务器从客户端接收请求并将请求发送到另一台服务器的可执行示例代码,这将 return 结果,并且应用程序服务器将 return 结果到客户.
我将服务器绑定在 localhost:9000 上,当我将请求发送到 localhost:9000/music?user=whatever
时,我首先得到了如下预期的结果。
[
"Music(Genre=Rock, Mood=[Joyful, Depressed])"
]
但是,再次发送相同的请求(使用邮递员),我得到了 []
作为 return。我无法理解这种行为,因为我希望每次发送请求时得到相同的结果 return。示例输入在控制器代码中硬编码为名为 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)
}
}
}
问题
Retrofit enqueue()
正在异步工作。所以它不会阻塞处理请求的当前线程。
因此,线程可以在收到来自 Retrofit 客户端的响应之前完成。
解决方案
使用springRestTemplate
代替Retrofit
使用阻塞改造 API(不是 enqueue()
)
我是 Spring + Kotlin 的新手,我正在尝试编写一个简单的服务器。我正在尝试编写一个应用程序服务器从客户端接收请求并将请求发送到另一台服务器的可执行示例代码,这将 return 结果,并且应用程序服务器将 return 结果到客户.
我将服务器绑定在 localhost:9000 上,当我将请求发送到 localhost:9000/music?user=whatever
时,我首先得到了如下预期的结果。
[
"Music(Genre=Rock, Mood=[Joyful, Depressed])"
]
但是,再次发送相同的请求(使用邮递员),我得到了 []
作为 return。我无法理解这种行为,因为我希望每次发送请求时得到相同的结果 return。示例输入在控制器代码中硬编码为名为 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)
}
}
}
问题
Retrofit enqueue()
正在异步工作。所以它不会阻塞处理请求的当前线程。
因此,线程可以在收到来自 Retrofit 客户端的响应之前完成。
解决方案
使用spring
RestTemplate
代替Retrofit使用阻塞改造 API(不是
enqueue()
)