我正在使用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字符串?
这原来是我的一部分的几个错误,虽然我不确定这是最好的解决方案,它确实工作。这里是所有感兴趣的人的完整代码。成功的关键因素:
- 必须使用
receive-jason
事件来捕获完整的json结果。data
事件似乎只返回最终文本 - 结果数据必须包装在一个有效的json包装-
data:{message:data}
(这是我的大错误) - 不要在ajax调用中包含
contentType: 'application/json; charset=utf-8',
,否则控制器将无法识别json数据 - Watson Java SDK
WebSocketManager
接收来自Watson的okhttp3.ResponseBody
,并从中提取字符串。我认为这类似于javascript SDK接收的内容,所以我使用了来自WebSocketManager
的相同代码来转换JSON。stringify string到控制器中的一个SpeechResults对象。
From okhttp3。ResponseBody javadoc:
从源服务器到客户端应用程序的一次性流,包含响应体的原始字节
沃森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 post 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);
});
}
<<p> 春控制器/strong> @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
,所以我会继续玩这个,但至少我有一个工作的解决方案。