我正在使用Watson Java SDK将watson-speech.js javascript库与基于Spring的服务器集成。我正试图将WatsonSpeech.SpeechToText.recognizeMicrophone
调用的输出发送到服务器而没有运气。 Speech java类似乎具有与客户端发送的json匹配的相应@SerializedName
注释,但我从Jackson获得了UnrecognizedPropertyException
个错误。
Unrecognized field "keywords_result" (class com.ibm.watson.developer_cloud.speech_to_text.v1.model.SpeechResults), not marked as ignorable (2 known properties: "resultIndex", "results"])
这是控制器方法:
@RequestMapping(value = "/postWatsonRequest", method = RequestMethod.POST)
@ResponseBody
@ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonRequest(@RequestBody SpeechResults speechResults) {
...
}
我显然遗漏了一些东西。我是否需要在服务器端手动解压缩json(自定义反序列化器?)或将其格式化为客户端可接受的json字符串?
答案 0 :(得分:3)
我发现这是一个错误,虽然我不确定这是否是最好的解决方案。这是任何有兴趣的人的完整代码。使其发挥作用的关键因素:
receive-jason
事件来捕获完整的json结果。 data
事件似乎仅返回最终文本data:{message:data}
(这是我的大错误)contentType: 'application/json; charset=utf-8',
,否则控制器将无法识别json数据WebSocketManager
从Watson收到okhttp3.ResponseBody
,从中提取字符串。我认为这与javascript SDK收到的类似,所以我使用WebSocketManager
中的相同代码将JSON.stringify字符串转换为控制器中的SpeechResults对象。 来自okhttp3.ResponseBody javadoc:
从源服务器到客户端应用程序的一次性流,包含响应主体的原始字节
Watson javascript
function listen(token) {
stream = WatsonSpeech.SpeechToText.recognizeMicrophone({
token: token,
readableObjectMode: true,
objectMode: true,
word_confidence: true,
format: false,
keywords: keywordsArray,
keywords_threshold : 0.5,
continuous : false
//interim_results : false
//keepMicrophone: navigator.userAgent.indexOf('Firefox') > 0
});
stream.setEncoding('utf8');
stream.on('error', function(err) {
console.log(err);
stream.stop();
});
stream.on('receive-json', function(msg) {
console.log(msg);
if (msg.state != 'listening') {
if (msg.results[0].final) {
console.log('receive-json: ' + msg);
postResults(msg);
stream.stop();
}
}
});
}
Ajax帖子
function postResults(results) {
var data = JSON.stringify(results);
console.log('stringify: ' + data);
$.ajax({
type: 'POST',
url: appContextPath + '/postWatsonResult',
dataType: 'json',
data: {message:data}
})
.done(function(data) {
console.log('done data: '+ data);
})
.fail(function(jqXHR, status, error) {
var data = jqXHR.responseJSON;
console.log('fail data: '+ data);
});
}
Spring控制器
@RequestMapping(value = "/postWatsonResult", method = RequestMethod.POST)
@ResponseBody
@ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonResult(@RequestParam("message") String message, Locale locale) {
logger.info("postWatsonRequest");
JsonObject json = new JsonParser().parse(message).getAsJsonObject();
SpeechResults results = null;
if (json.has("results")) {
results = GSON.fromJson(message, SpeechResults.class);
}
if (results != null) {
logger.debug("results: " + results.getResults().get(0).getAlternatives().get(0).getTranscript());
}
return new ResponseObject();
}
我仍然认为应该可以某种方式使用@RequestBody SpeechResults speechResults
所以我会继续玩这个,但至少我有一个有效的解决方案。