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

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

到目前为止,我已经获得了两种语言的语音识别功能,并且我决定使用MyMemory的API作为REST API进行翻译。 我正在使用Retrofit 2.0.0-beta2将HTTP API变成Java界面。

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

目前,我的项目中有三个类:

  • TranslateAPI(界面)
  • TranslatedData
  • 主要活动
  • 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的教程模糊和混乱,因为一半的指南是在Retrofit 1.x和另一半2.0中编写的。


    Retrofit提供注释来构建适当的调用,顺便提一下,在这种特殊情况下,您需要构建这种类型的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 - " + "");
                    }
                });
        }
    }
    

    你可以这样调用翻译方法:

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

    我的控制台结果:

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

    在Android Studio上,底部有Android Monitor ,您可以在其中找到带有错误和更多信息的堆栈轨迹,错误将以红色突出显示。

    Android监视器

    要使用Retrofit 2.0解析来自服务器的响应,您需要指定一个转换器。 例如:如果你想首先使用Gson作为你的Entity转换器,你必须将该依赖添加到你的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个教程,这可能是:)

    链接地址: http://www.djcxy.com/p/29505.html

    上一篇: Using Retrofit 2.0 to extract information from a network API

    下一篇: OkHttp + Retrofit libssl crash in two way SSL authentication