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 所以我会继续尝试这个,但至少我有一个可行的解决方案。