繁体   English   中英

使用Retrofit 2.0从网络API提取信息

[英]Using Retrofit 2.0 to extract information from a network API

我是Java编程的新手,在过去的几天中,我一直在尝试使用基本的英语到希腊语语音翻译应用程序,纯粹是为了帮助我学习一些(更高级的)概念。 这是界面图片

到目前为止,我已经将语音识别功能同时支持两种语言,并且我决定将MyMemory的API用作REST API进行翻译。 我正在使用Retrofit 2.0.0-beta2将HTTP API转换为Java接口。

目前,我只是想从MyMemory中提取单词/短语的翻译,并将其放在应用程序内的文本字段中。

目前,我的项目中有三个班级:

  1. TranslateAPI(接口)
  2. TranslatedData
  3. 主要活动

TranslateAPI

public interface TranslateAPI {
    @GET("get")
    void getTranslation(@Query("q") String request, Callback<TranslatedData> cb);
}

TranslatedData

public class TranslatedData {
    String translatedText;

    public String getTranslatedText(){
        return translatedText;
    }
}

MainActivity(相关代码)

        public void translate(String toTranslate){
        String request = "=" + toTranslate + "&langpair=" + langPair;
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.mymemory.translated.net/")
                .build();
        TranslateAPI service = retrofit.create(TranslateAPI.class);
        service.getTranslation(request, new Callback<TranslatedData>() {
            @Override
            public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
                System.out.println("Success");
                //handle success
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("Failure");
                //handle failure
            }
        });        
    }

这里出现一些问题。 首先,应用程序由于translate()方法而崩溃,我无法理解为什么(我的android调试技能仍然不存在)。 谁能帮我找出原因吗?

其次,我如何准确地解析服务器的响应?

我的代码是否还有其他缺陷会阻止应用程序正常工作/崩溃?

如果我的问题仍然很简单或很直接,我深表歉意。我仍然是Android的新手,并且由于有关指南的一半是用Retrofit 1.x编写而另一半是2.0的事实,我发现大多数有关Retrofit的教程含糊不清且令人困惑。

在Android Studio的底部,您具有Android Monitor ,您可以在其中找到包含错误和更多信息的堆栈跟踪,错误将以红色突出显示。

Android显示器

要使用Retrofit 2.0解析来自服务器的响应,您需要指定一个转换器。 示例:如果首先要使用Gson作为实体转换器,则必须将该依赖项添加到build.gradle文件中。

compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'

然后,您必须将其指定到Retrofit适配器中:

 Retrofit marvelApiAdapter = new Retrofit.Builder()
    .baseUrl(END_POINT)
    .addConverterFactory(GsonConverterFactory.create(new Gson()))
    .client(client)
    .build();

如果没有,您将崩溃。 也许最好的建议是您现在应该使用Retrofit 1.9,该版本很稳定,在撰写本文时,第二个版本是beta版。 在另一方面在这个环节上 ,你会发现如何从1.9版本到2.0版本迁移一个很好的指南,如果你是以下1.9教程,这可能是:)

顺便说一下,翻新提供了注释以构建适当的调用,在这种特殊情况下,您需要构建这种URI:

http://api.mymemory.translated.net/get?q=hola&langpair=ES|EN

的参数值langpair包括字符:| 需要逃脱(我花了一些时间),这可能是崩溃的原因。

您可以轻松地对其进行修复,以将参数设置为Retrofit 2 API声明的签名中编码的形式:

@GET("/get")
Call<TranslatedData> getTranslation(
    @Query("q") String textToTranslate, 
    @Query(value = "langpair", encoded = true) 
String languagePair);

然后编码参数值:

mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
    .enqueue(new Callback<TranslatedData>() {

另外,您的响应实体中存在一些错误,包含translatedText属性的对象是一个名为responseData的JsonObject,您需要设置适当的实体:

class TranslatedData {
    ResponseData responseData;
}

class ResponseData {
    String translatedText;
}

我向您发布了TranslateApi.java的整个文件,我已经对其进行了测试并可以工作;)

package com.example.alex.finalproject;

import java.net.URLEncoder;
import retrofit.Call;
import retrofit.Callback;
import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;
import retrofit.http.GET;
import retrofit.http.Query;

class TranslatedData {
    ResponseData responseData;
}

class ResponseData {
    String translatedText;
}

public class TranslateAPI {
    private static final String ENDPOINT = "http://api.mymemory.translated.net";
    public final static String SPANISH = "ES";
    public final static String ENGLISH = "EN";


    private final TranslateService mService;

    public interface TranslateService {
        @GET("/get")
        Call<TranslatedData> getTranslation(
            @Query("q") String textToTranslate,
            @Query(value = "langpair", encoded = true)
        String languagePair);
    }

    public TranslateAPI() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ENDPOINT)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        mService = retrofit.create(TranslateService.class);
    }

    public void translate(final String textToTranslate, final String fromLanguage, final String toLanguage) {
        mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
            .enqueue(new Callback<TranslatedData>() {

                @Override
                public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
                    String output =
                        String.format("Translation of: %s, %s->%s = %s", textToTranslate,
                            fromLanguage, toLanguage, response.body().responseData.translatedText);

                    System.out.println("Result: " + output);
                }

                @Override public void onFailure(Throwable t) {
                    System.out.println("[DEBUG]" + " RestApi onFailure - " + "");
                }
            });
    }
}

您可以通过以下方式调用translate方法:

translateAPI.translate("hola", TranslateAPI.SPANISH, TranslateAPI.ENGLISH);

我的控制台结果:

I/System.out(31427): Result: Translation of: hola, ES->EN = hello

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM