I have been trying to make an app which fetches data about etymology from the oxford dictionary app. On trying to use retrofit, to get data, onFailiure() is always called. I will be uploading my code and also the correct code but the one which uses HttpsURLConnection instead for reference.
I thought that the app_key and app_id aren't sent to the server properly and so I tried to send these in various ways. First way to add @Headers tag
@Headers({"Accept: application/json","app_id: ********","app_key: ******************"})
I also tried an interceptor to add header.
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Request newRequest;
newRequest = request.newBuilder()
.addHeader(Accept,"application/json").addHeader(app_id,"*******").addHeader(app_key,"**********")
.build();
return chain.proceed(newRequest);
}
and then adding client to retrofit.
But all of these returned the same error.
Here is my code using retrofit.
MainActivity.java
public class MainActivity extends AppCompatActivity {
GetDataInterface INTERFACE;
WordDetails wordclass;
TextView temp;
final String app_id = "*********";
final String app_key = "***************";
final String theword = "chaos";
final String word_id = theword.toLowerCase();
final String TheAdd = "https://od-api.oxforddictionaries.com:443/api/v2/entries/en-gb/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
temp = (TextView)findViewById(R.id.temp);
wordclass = new WordDetails();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://od-api.oxforddictionaries.com:443/api/v2/entries/en-gb/")
.addConverterFactory(GsonConverterFactory.create())
.build();
INTERFACE = retrofit.create(GetDataInterface.class);
Call<WordDetails> call = INTERFACE.getData(word_id,"etymologies","false");
call.enqueue(new Callback<WordDetails>() {
@Override
public void onResponse(Call<WordDetails> call, Response<WordDetails> response) {
if(!response.isSuccessful())
{
System.out.println("Server Error.");
return;
}
wordclass = new WordDetails();
wordclass=response.body();
if(wordclass.getResults().getLexicalEntries().getEntries().getEtymologies()!=null)
{
temp.setText(wordclass.getResults().getLexicalEntries().getEntries().getEtymologies());
}
else
temp.setText("ERROR");
}
@Override
public void onFailure(Call<WordDetails> call, Throwable t) {
System.out.println("Failed to fetch.");
}
});
}
Throwable throws
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 8 column 17 path $.results
GetDataInterface.java
public interface GetDataInterface {
final String app_id = "*********";
final String app_key = "************";
final String Accept = "application/json";
@Headers({"Accept: "+Accept,"app_id: "+app_id,"app_key: "+app_key})
@GET("{id}")
Call<WordDetails> getData(@Path("id") String Sambhar, @Query("fields") String Mirchi, @Query("strictMatch") String Trichy);
}
WordDetails.java
public class WordDetails {
Results results;
public Results getResults()
{
return results;
}
public WordDetails()
{
results = new Results();
}
class Results
{
Lexical lexicalEntries;
public Results()
{
lexicalEntries = new Lexical();
}
public Lexical getLexicalEntries() {
return lexicalEntries;
}
class Lexical
{
Entries entries;
public Lexical()
{
entries = new Entries();
}
public Entries getEntries() {
return entries;
}
class Entries
{
String etymologies;
public Entries()
{
etymologies="";
}
public String getEtymologies() {
return etymologies;
}
}
}
}
}
Logcat for this is
2019-07-04 16:45:25.872 22520-22616/? I/Adreno: Build Config : S L 6.0.7 AArch64
2019-07-04 16:45:25.879 22520-22616/? I/Adreno: PFP: 0x005ff112, ME: 0x005ff066
2019-07-04 16:45:25.884 22520-22616/? I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2019-07-04 16:45:25.885 22520-22616/? I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
2019-07-04 16:45:25.885 22520-22616/? I/OpenGLRenderer: Initialized EGL, version 1.4
2019-07-04 16:45:25.885 22520-22616/? D/OpenGLRenderer: Swap behavior 2
2019-07-04 16:45:26.955 22520-22614/com.example.spidertask3_v2 W/.spidertask3_v: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (light greylist, reflection)
2019-07-04 16:45:28.677 22520-22614/com.example.spidertask3_v2 W/.spidertask3_v: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B (light greylist, reflection)
2019-07-04 16:45:29.121 22520-22520/com.example.spidertask3_v2 I/System.out: Failed to fetch. com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 8 column 17 path $.results
The sample data is of the following form
{
"metadata": {},
"results": [
{
"id": "string",
"language": "string",
"lexicalEntries": [
{
"derivativeOf": [
{
"domains": [
{
"id": "string",
"text": "string"
}
],
"id": "string",
"language": "string",
"regions": [
{
"id": "string",
"text": "string"
}
],
"registers": [
{
"id": "string",
"text": "string"
}
],
"text": "string"
}
],
"derivatives": [
{
"domains": [
{
"id": "string",
"text": "string"
}
],
"id": "string",
"language": "string",
"regions": [
{
"id": "string",
"text": "string"
}
],
"registers": [
{
"id": "string",
"text": "string"
}
],
"text": "string"
}
],
"entries": [
{
"etymologies": [
"string"
],
"grammaticalFeatures": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"homographNumber": "string",
"notes": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"pronunciations": [
{
"audioFile": "string",
"dialects": [
"string"
],
"phoneticNotation": "string",
"phoneticSpelling": "string",
"regions": [
{
"id": "string",
"text": "string"
}
]
}
],
"senses": [
{
"crossReferenceMarkers": [
"string"
],
"crossReferences": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"definitions": [
"string"
],
"domains": [
{
"id": "string",
"text": "string"
}
],
"examples": [
{
"definitions": [
"string"
],
"domains": [
{
"id": "string",
"text": "string"
}
],
"notes": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"regions": [
{
"id": "string",
"text": "string"
}
],
"registers": [
{
"id": "string",
"text": "string"
}
],
"senseIds": [
"string"
],
"text": "string"
}
],
"id": "string",
"notes": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"pronunciations": [
{
"audioFile": "string",
"dialects": [
"string"
],
"phoneticNotation": "string",
"phoneticSpelling": "string",
"regions": [
{
"id": "string",
"text": "string"
}
]
}
],
"regions": [
{
"id": "string",
"text": "string"
}
],
"registers": [
{
"id": "string",
"text": "string"
}
],
"shortDefinitions": [
"string"
],
"subsenses": [
{}
],
"thesaurusLinks": [
{
"entry_id": "string",
"sense_id": "string"
}
],
"variantForms": [
{
"domains": [
{
"id": "string",
"text": "string"
}
],
"notes": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"pronunciations": [
{
"audioFile": "string",
"dialects": [
"string"
],
"phoneticNotation": "string",
"phoneticSpelling": "string",
"regions": [
{
"id": "string",
"text": "string"
}
]
}
],
"regions": [
{
"id": "string",
"text": "string"
}
],
"registers": [
{
"id": "string",
"text": "string"
}
],
"text": "string"
}
]
}
],
"variantForms": [
{
"domains": [
{
"id": "string",
"text": "string"
}
],
"notes": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"pronunciations": [
{
"audioFile": "string",
"dialects": [
"string"
],
"phoneticNotation": "string",
"phoneticSpelling": "string",
"regions": [
{
"id": "string",
"text": "string"
}
]
}
],
"regions": [
{
"id": "string",
"text": "string"
}
],
"registers": [
{
"id": "string",
"text": "string"
}
],
"text": "string"
}
]
}
],
"grammaticalFeatures": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"language": "string",
"lexicalCategory": {
"id": "string",
"text": "string"
},
"notes": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"pronunciations": [
{
"audioFile": "string",
"dialects": [
"string"
],
"phoneticNotation": "string",
"phoneticSpelling": "string",
"regions": [
{
"id": "string",
"text": "string"
}
]
}
],
"text": "string",
"variantForms": [
{
"domains": [
{
"id": "string",
"text": "string"
}
],
"notes": [
{
"id": "string",
"text": "string",
"type": "string"
}
],
"pronunciations": [
{
"audioFile": "string",
"dialects": [
"string"
],
"phoneticNotation": "string",
"phoneticSpelling": "string",
"regions": [
{
"id": "string",
"text": "string"
}
]
}
],
"regions": [
{
"id": "string",
"text": "string"
}
],
"registers": [
{
"id": "string",
"text": "string"
}
],
"text": "string"
}
]
}
],
"pronunciations": [
{
"audioFile": "string",
"dialects": [
"string"
],
"phoneticNotation": "string",
"phoneticSpelling": "string",
"regions": [
{
"id": "string",
"text": "string"
}
]
}
],
"type": "string",
"word": "string"
}
]
}
Now the one using HttpsURLConnection and which works well. (for reference to help me with the retrofit code)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TEMP = (TextView) findViewById(R.id.TEMP);
new CallbackTask().execute(dictionaryEntries());
}
private String dictionaryEntries() {
final String language = "en-gb";
final String word = "chaos";
final String fields = "etymologies";
final String strictMatch = "false";
final String word_id = word.toLowerCase();
return "https://od-api.oxforddictionaries.com:443/api/v2/entries/" + language + "/" + word_id + "?" + "fields=" + fields + "&strictMatch=" + strictMatch;
}
private class CallbackTask extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
final String app_id = "********";
final String app_key = "******************";
try {
URL url = new URL(params[0]);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestProperty("Accept","application/json");
urlConnection.setRequestProperty("app_id",app_id);
urlConnection.setRequestProperty("app_key",app_key);
// read the output from the server
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
return stringBuilder.toString();
}
catch (Exception e) {
e.printStackTrace();
return e.toString();
}
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
TEMP.setText(result);
}
}
Output for this as an app is something like https://ibb.co/0FCtG21
I would want to have the data (etymology of chaos) to be shown in the textview using retrofit. HttpsURLConnection is for reference to show the nature of oxford api.
As it turns out, my WordDetails.class was wrong. All the variables had to be in the form of list.
public class WordDetails {
List<Results> results;
public List<Results> getResults()
{
return results;
}
class Results
{
List<Lexical> lexicalEntries;
public List<Lexical> getLexicalEntries() {
return lexicalEntries;
}
class Lexical
{
List<Entries> entries;
public List<Entries> getEntries() {
return entries;
}
class Entries
{
List<String> etymologies;
public List<String> getEtymologies() {
return etymologies;
}
}
}
}
}