Watson SpeechToText Java 和 javascript 模型差异
Watson SpeechToText Java and javascript model differences
我正在使用 Watson Java SDK 将 watson-speech.js java 脚本库与基于 Spring 的服务器集成。我试图将 WatsonSpeech.SpeechToText.recognizeMicrophone
调用的输出发送到服务器,但没有成功。语音 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
事件只出现在 return 最终文本
- 结果数据必须包装在有效的 json 包装器中 -
data:{message:data}
(这是我的大错误)
- 不要在 ajax 调用中包含
contentType: 'application/json; charset=utf-8',
否则控制器将无法识别 json 数据
- Watson Java SDK
WebSocketManager
收到来自 Watson 的 okhttp3.ResponseBody
,并从中提取字符串。我认为这类似于 javascript SDK 收到的内容,因此我使用来自 WebSocketManager
的相同代码将 JSON.stringify 字符串转换为控制器中的 SpeechResults 对象。
来自 okhttp3.ResponseBody javadoc:
A one-shot stream from the origin server to the client application with the raw bytes of the response body
沃森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);
});
}
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
所以我会继续尝试这个,但至少我有一个可行的解决方案。
我正在使用 Watson Java SDK 将 watson-speech.js java 脚本库与基于 Spring 的服务器集成。我试图将 WatsonSpeech.SpeechToText.recognizeMicrophone
调用的输出发送到服务器,但没有成功。语音 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
事件只出现在 return 最终文本 - 结果数据必须包装在有效的 json 包装器中 -
data:{message:data}
(这是我的大错误) - 不要在 ajax 调用中包含
contentType: 'application/json; charset=utf-8',
否则控制器将无法识别 json 数据 - Watson Java SDK
WebSocketManager
收到来自 Watson 的okhttp3.ResponseBody
,并从中提取字符串。我认为这类似于 javascript SDK 收到的内容,因此我使用来自WebSocketManager
的相同代码将 JSON.stringify 字符串转换为控制器中的 SpeechResults 对象。
来自 okhttp3.ResponseBody javadoc:
A one-shot stream from the origin server to the client application with the raw bytes of the response body
沃森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);
});
}
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
所以我会继续尝试这个,但至少我有一个可行的解决方案。