【问题标题】:retrofit returning object params out of order, with @ sign and quotes改造返回对象参数乱序,带有@符号和引号
【发布时间】:2018-10-26 21:38:28
【问题描述】:

我正在使用改造向 api 发送调用,以通过我的 android 应用程序在错误跟踪器中发布问题。 API 需要以特定方式对其进行格式化,因此我创建了一个自定义对象作为参数传递。不幸的是,当我将请求发送到 API 时,它的格式不正确。它按字母顺序排列参数,在键和值周围加上引号,并在我的数据开头添加一个 @,导致 API 无法理解我试图发布的内容。我要发送的格式是:

{ fb_user_id: dummyUID, 
email: dummy@email.com, 
first_name: John, 
last_name: Smith, 
project: android, 
type: bug, 
subject: title, 
description: description }

与上述不同,我的 api 接收数据为

@"description":"description",
"email":"dummy@email.com",
"fb_user_id":"dummyUID",
"first_name":"John",
"last_name":"Smith",
"project":"android",
"subject":"title",
"type":"bug"

我正在使用改造来做到这一点,我的界面看起来像

public interface MyAPI {
@POST("/op_create_ticket")
Observable<JsonElement> createTicket(@Body Ticket ticket);
}

我的活动称之为:

public class HelpActivity extends BaseActivity {

    @BindView(R.id.textView)
    TextView textView;
    @BindView(R.id.spinner)
    Spinner spinner;
    @BindView(R.id.email)
    EditText email;
    @BindView(R.id.firstName)
    EditText firstName;
    @BindView(R.id.lastName)
    EditText lastName;
    @BindView(R.id.subject)
    EditText title;
    @BindView(R.id.description)
    EditText description;
    @BindView(R.id.button3)
    Button button3;

    FirebaseAuth fbauth = FirebaseAuth.getInstance();
    FirebaseUser user = fbauth.getCurrentUser();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_help);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.button3)
    public void onViewClicked() {
        final GsonBuilder gsonBuilder = new GsonBuilder();
        final Gson gson = gsonBuilder.create();
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl("https://my.url");
        builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
        builder.addConverterFactory(GsonConverterFactory.create());

        Retrofit retrofit = builder.build();
        MyAPI api = retrofit.create(TriggerWatchAPI.class);

        Ticket ticket = new Ticket();
        ticket.setFb_user_id(user.getUid());
        ticket.setEmail(email.getText().toString());
        ticket.setFirst_name(firstName.getText().toString());
        ticket.setLast_name(lastName.getText().toString());
        ticket.setProject("android");
        ticket.setType("design");
        ticket.setSubject(title.getText().toString());
        ticket.setDescription(description.getText().toString());

        api.createTicket(ticket).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<JsonElement>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(JsonElement jsonElement) {
                        Log.d(getTag(), "zzzOnNext");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(getTag(), "err", e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

我想知道是否有任何类型的转换器或可以将我的对象转换为 API 正在寻找的数据类型的东西。

编辑:忘记添加我的自定义 pojo

package watch.trigger.Model;

public class Ticket {

        private String project;

        private String first_name;

        private String email;

        private String description;

        private String subject;

        private String last_name;

        private String fb_user_id;

        private String type;

        public String getProject ()
        {
            return project;
        }

        public void setProject (String project)
        {
            this.project = project;
        }

        public String getFirst_name ()
        {
            return first_name;
        }

        public void setFirst_name (String first_name)
        {
            this.first_name = first_name;
        }

        public String getEmail ()
        {
            return email;
        }

        public void setEmail (String email)
        {
            this.email = email;
        }

        public String getDescription ()
        {
            return description;
        }

        public void setDescription (String description)
        {
            this.description = description;
        }

        public String getSubject ()
        {
            return subject;
        }

        public void setSubject (String subject)
        {
            this.subject = subject;
        }

        public String getLast_name ()
        {
            return last_name;
        }

        public void setLast_name (String last_name)
        {
            this.last_name = last_name;
        }

        public String getFb_user_id ()
        {
            return fb_user_id;
        }

        public void setFb_user_id (String fb_user_id)
        {
            this.fb_user_id = fb_user_id;
        }

        public String getType ()
        {
            return type;
        }

        public void setType (String type)
        {
            this.type = type;
        }

        @Override
        public String toString()
        {
            return "ClassPojo [project = "+project+", first_name = "+first_name+", email = "+email+", description = "+description+", subject = "+subject+", last_name = "+last_name+", fb_user_id = "+fb_user_id+", type = "+type+"]";
        }
    }

【问题讨论】:

  • 请添加Ticket.class的代码
  • 刚刚意识到丢失了
  • 可以添加改造日志吗?
  • 对改造不熟悉,但 API 期待 JSON?是否有要设置的标头或注释来告诉它发送 JSON?
  • 如果不使用引号,它实际上是 json 吗?我以为 json 会有引号

标签: java android json gson retrofit2


【解决方案1】:

不要发送自定义对象,将 JSON 对象作为字符串发送,并在 API 中将其作为 JSON 对象接收。

首先在你的 gradle 中添加这个:

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:converter-scalars:2.3.0'

1-改变这个

public interface MyAPI {

@Headers("Content-Type: application/json")
@POST("/op_create_ticket")
Observable<JsonElement> createTicket(@Body Ticket ticket);
}

到:

public interface MyAPI {
@POST("/op_create_ticket")
Observable<String> createTicket(@Body String ticket);
}

2- 改变这个

Ticket ticket = new Ticket();
    ticket.setFb_user_id(user.getUid());
    ticket.setEmail(email.getText().toString());
    ticket.setFirst_name(firstName.getText().toString());
    ticket.setLast_name(lastName.getText().toString());
    ticket.setProject("android");
    ticket.setType("design");
    ticket.setSubject(title.getText().toString());
    ticket.setDescription(description.getText().toString());

    api.createTicket(ticket).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<JsonElement>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(JsonElement jsonElement) {
                    Log.d(getTag(), "zzzOnNext");
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(getTag(), "err", e);
                }

                @Override
                public void onComplete() {

                }
            });

  JSONObject tickenJson= new JSONObject();

        Ticket ticket = new Ticket();
        ticket.setFb_user_id(user.getUid());
        ticket.setEmail(email.getText().toString());
        ticket.setFirst_name(firstName.getText().toString());
        ticket.setLast_name(lastName.getText().toString());
        ticket.setProject("android");
        ticket.setType("design");
        ticket.setSubject(title.getText().toString());
        ticket.setDescription(description.getText().toString());

ticketJson.put("fb_user_id",user.getUid());
ticketJson.put("email",email.getText().toString());
ticketJson.put("first_name",firstName.getText().toString());
ticketJson.put("last_name",lastName.getText().toString());
ticketJson.put("project","android");
ticketJson.put("type","design");
ticketJson.put("type",title.getText().toString());
ticketJson.put("description",description.getText().toString());
     api.createTicket(ticketJson.toString()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<JsonElement>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(JsonElement jsonElement) {
                        Log.d(getTag(), "zzzOnNext");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(getTag(), "err", e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });

【讨论】:

  • JsonObject.put 似乎不是一个有效的方法。你是说 ticketJson.addProperty 吗?
  • android 中有两个 JSON 类。是的,ticketJson.addProperty 等于 ticketJson.put
  • 之后我得到的响应是 Data:"@\"fb_user_id\":\"CSLbKEtCMqf4py73Gih2udifxq73\",\"email\":\"test@email.com\",\"first_name \":\"First \",\"last_name\":\"Last\",\"project\":\"design\",\"subject\":\"Demo\",\"description\" :\"虚拟文本\""
  • 请使用“JSONObject”,它是 JSON 的另一个类。查看答案更新
  • 不要忘记添加标题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
相关资源
最近更新 更多