java - Rest API + Json 响应编码错误(我认为)

标签 java android json rest

我正在开发一个自动注册屏幕,并使用restful api根据用户通知的CEP(邮政编码)获取数据。 (“cep”是巴西邮政编码 ID 的名称)。

我遇到的问题显然很容易解决。

当我调用rest api来获取有关地址的数据时,有时解决方案有效,有时则无效。

我通过网址获取数据:http://api.postmon.com.br/v1/cep/70040903

我的代码是:

package com.clubee.doggywalker;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by barcat on 6/24/15.
 */
public class cadastro_user extends ActionBarActivity {

//JSON node
private static final String TAG_SUCCESS = "success";

//url para cadastrar novo usuário
private static String url_cadastraCliente = "http://clubee.com.br/dev/dbDoggyWalker/DoggyWalker_CadastroUsuario_Inserir.php";

JSONParser jsonParser = new JSONParser();

EditText char_Nome;
EditText char_CEP;
EditText char_Email;
EditText char_Cidade;
EditText char_Estado;
EditText char_Logradouro;
EditText char_Endereco;
EditText char_Bairro;

//barra de progressão
private ProgressDialog pDialog;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.cadastro_user);

    char_Nome = (EditText) findViewById(R.id.inputNome);
    char_Email = (EditText) findViewById(R.id.inputEmail);
    char_Logradouro = (EditText) findViewById(R.id.inputLogradouro);
    char_Endereco = (EditText) findViewById(R.id.inputLogradouro2);
    char_Cidade = (EditText) findViewById(R.id.inputCidade);
    char_Estado = (EditText) findViewById(R.id.inputEstado);
    char_Bairro = (EditText)findViewById(R.id.inputBairro);
    char_CEP = (EditText) findViewById(R.id.inputCEP);

    //Criar botão
    Button btnCadastraUsuario = (Button) findViewById(R.id.btnCadastraUsuario);
    Button btnBuscaCEP = (Button) findViewById(R.id.btnBuscaEndereco);

    //Criar evento do botão
    btnCadastraUsuario.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //abre thread em background
            new CadastraCliente().execute();
        }
    });

    //Criar evento do botão
    btnBuscaCEP.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //abre thread em background
            new HttpRequestTask().execute();
        }
    });
}

private class HttpRequestTask extends AsyncTask<Void, Void, Greeting> {
    @Override
    protected Greeting doInBackground(Void... params) {
        try {
            final String url = "http://api.postmon.com.br/v1/cep/"+char_CEP.getText();
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
            Greeting greeting = restTemplate.getForObject(url, Greeting.class);
            return greeting;
        } catch (Exception e) {
            Log.e("cadastro_user", e.getMessage(), e);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Greeting greeting) {
        TextView greetingLogradouro = (TextView) findViewById(R.id.inputLogradouro);
        TextView greetingEndereco = (TextView) findViewById(R.id.inputLogradouro2);
        TextView greetingBairro = (TextView) findViewById(R.id.inputBairro);
        TextView greetingCidade = (TextView) findViewById(R.id.inputCidade);
        TextView greetingEstado = (TextView) findViewById(R.id.inputEstado);
        TextView greetingCEP = (TextView) findViewById(R.id.inputCEP);
        greetingLogradouro.setText(greeting.getLogradouro());
        greetingEndereco.setText(greeting.getEndereco());
        greetingCidade.setText(greeting.getCidade());
        greetingBairro.setText(greeting.getBairro());
        greetingEstado.setText(greeting.getEstado());
        greetingCEP.setText(greeting.getCep());
    }
}

class CadastraCliente extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(cadastro_user.this);
        pDialog.setMessage("Cadastrando usuário..");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    /**
     * Creating product
     */
    protected String doInBackground(String... args) {
        String Nome = char_Nome.getText().toString();
        String Email = char_Email.getText().toString();
        String Endereco = char_Logradouro.getText().toString();
        String TipoLicenca = "Usuario";


        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("char_Nome", Nome));
        params.add(new BasicNameValuePair("char_Email", Email));
        params.add(new BasicNameValuePair("char_Endereco", Endereco));
        params.add(new BasicNameValuePair("char_TipoLicenca",TipoLicenca));


        // getting JSON Object
        // Note that create product url accepts POST method
        JSONObject json = jsonParser.makeHttpRequest(url_cadastraCliente,
                "POST", params);

        // check log cat fro response
        Log.d("Create Response", json.toString());

        // check for success tag
        try {
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {
                // successfully created product
                Intent i = new Intent(getApplicationContext(), cadastro_user.class);
                startActivity(i);

                // closing this screen
                finish();
            } else {
                // failed to create product
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * *
     */
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once done
        pDialog.dismiss();
    }
}
}

我的 DAO 是

package com.clubee.doggywalker;

import java.lang.ref.SoftReference;

/**
 * Created by barcat on 6/26/15.
 */
public class Greeting {

private String logradouro;
private String cep;
private String bairro;
private String cidade;
private String estado;
private String complemento;
private String unidade;
private String endereco;


public String getBairro() {
    return this.bairro;
}

public String getLogradouro() {
    return this.logradouro;
}

public String getEndereco() {
    return this.endereco;
}

public String getCidade() {
    return this.cidade;
}

public String getCep() {
    return this.cep;
}

public String getEstado() {
    return this.estado;
}

public String getComplemento() {
    return this.complemento;
}

public String getUnidade() {
    return this.unidade;
}

}

异常(exception)是

06-27 19:35:11.696 5845-6029/com.clubee.doggywalker E/cadastro_user﹕ Could not read JSON: Unrecognized field "endereço" (class com.clubee.doggywalker.Greeting), not marked as ignorable (8 known properties: "cidade", "logradouro", "bairro", "estado", "complemento", "endereco", "cep", "unidade"]) at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$FixedLengthSource@2ed70b18).inputStream(); line: 1, column: 70] (through reference chain: com.clubee.doggywalker.Greeting["endereço"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "endereço" (class com.clubee.doggywalker.Greeting), not marked as ignorable (8 known properties: "cidade", "logradouro", "bairro", "estado", "complemento", "endereco", "cep", "unidade"]) at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$FixedLengthSource@2ed70b18).inputStream(); line: 1, column: 70] (through reference chain: com.clubee.doggywalker.Greeting["endereço"]) org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "endereço" (class com.clubee.doggywalker.Greeting), not marked as ignorable (8 known properties: "cidade", "logradouro", "bairro", "estado", "complemento", "endereco", "cep", "unidade"]) at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$FixedLengthSource@2ed70b18).inputStream(); line: 1, column: 70] (through reference chain: com.clubee.doggywalker.Greeting["endereço"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "endereço" (class com.clubee.doggywalker.Greeting), not marked as ignorable (8 known properties: "cidade", "logradouro", "bairro", "estado", "complemento", "endereco", "cep", "unidade"]) at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$FixedLengthSource@2ed70b18).inputStream(); line: 1, column: 70] (through reference chain: com.clubee.doggywalker.Greeting["endereço"]) at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readInternal(MappingJackson2HttpMessageConverter.java:126) at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:147) at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:76) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:484) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439) at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237) at com.clubee.doggywalker.cadastro_user$HttpRequestTask.doInBackground(cadastro_user.java:97) at com.clubee.doggywalker.cadastro_user$HttpRequestTask.doInBackground(cadastro_user.java:90) at android.os.AsyncTask$2.call(AsyncTask.java:297) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "endereço" (class com.clubee.doggywalker.Greeting), not marked as ignorable (8 known properties: "cidade", "logradouro", "bairro", "estado", "complemento", "endereco", "cep", "unidade"]) at [Source: buffer(com.android.okhttp.internal.http.HttpConnection$FixedLengthSource@2ed70b18).inputStream(); line: 1, column: 70] (through reference chain: com.clubee.doggywalker.Greeting["endereço"]) at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:671) at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:771) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1297) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1275) 06-27 19:35:11.697 5845-5845/com.clubee.doggywalker D/AndroidRuntime﹕ Shutting down VM 06-27 19:35:11.698 5845-5845/com.clubee.doggywalker E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.clubee.doggywalker, PID: 5845 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.clubee.doggywalker.Greeting.getLogradouro()' on a null object reference at com.clubee.doggywalker.cadastro_user$HttpRequestTask.onPostExecute(cadastro_user.java:114) at com.clubee.doggywalker.cadastro_user$HttpRequestTask.onPostExecute(cadastro_user.java:90) at android.os.AsyncTask.finish(AsyncTask.java:641) at android.os.AsyncTask.access$500(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:658) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:211) at android.app.ActivityThread.main(ActivityThread.java:5333) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)

最佳答案

在您的 Greeting 类中,您有:

private String endereco;

但是在你的数据中你有

"endere\u00e7o": "SBN Quadra 1 Bloco C"

这不匹配。

来自注释文档:

 @JsonProperty("firstName")
 public String _first_name;

参见 ( fasterXML annotations ) 因此您可能需要导入 fastXML 注释并将其添加到属性中

@JsonProperty("endere\u00e7o")
private String endereco;

我不确定这在 Android 中有多容易,但我认为它应该可以工作。 然后它应该解析。

一个“有趣”的替代方法是检查这个 stackoverflow 问题:unicode variable names

并使用

private String endere\u00e7o;

但我只是出于兴趣而尝试,我不认为使用这样的变量名称是一个好习惯;)

...

或者(正如我在评论中列出的那样)有时您的输入流中似乎有 endereco(带有 cedille 和不带有 cedille)。

要忽略任何不可映射的属性,您可以将其放在顶部:

@JsonIgnoreProperties(ignoreUnknown = true)

这将忽略任何不可映射的属性。当然,请检查您的数据流并检查 endereco(不带 cedille)是否始终存在,然后忽略 unicode 版本应该是安全的。

关于java - Rest API + Json 响应编码错误(我认为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31094309/

相关文章:

c# - 适用于 Android 的 Xamarin C# : creating a json string?

java - 返回子字符串的内容与返回子字符串本身

java - 如何在我的列表中的 simple_list_item_multiple_choice 中设置选中的 ="checked"项,如果我希望始终选中 2 个元素?

java - 匿名可运行实现并将其发布到处理程序

android - 在 Android 中连续旋转 ImageView

android - 使用 volley 发送 firebase 推送通知

java - 通过WebView.goBack执行url

java - 从奇怪的较大字符串(重复字符)中提取子字符串

java - 在java中,我如何检查用于输入成绩的数组的输入验证(不能为负数,不能超过100)

json - 在已使用引号的 sudo 封装的 sed 命令上使用引号