java - 使用 Retrofit with Field 传递参数

标签 java android retrofit

我正在学习一个改造类(class),其中我创建了一个带有 api 的小型后端,其中我有一个 POST 方法来执行教师的登录。在类(class)中,他所做的是创建一名教师,并使用 set 方法将电子邮件和密码传递给他,这是该方法在 API 中接收的内容。

我想这样做,在调用 Retrofit 时直接传递此电子邮件和密码,我已按以下方式完成:

public class LoginActivity extends AppCompatActivity {

    private EditText etPasswordLogin, etEmailLogin;
    private Button btLogin;
    private TextView tvSignUp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        setupView();
    }

    private void setupView() {

        etPasswordLogin = findViewById(R.id.loginEditTextPassword);
        etEmailLogin = findViewById(R.id.loginEditTextEmail);
        btLogin = findViewById(R.id.buttonSignUp);
        tvSignUp = findViewById(R.id.textViewSignUp);

        btLogin.setOnClickListener(v -> userSignUp());
        tvSignUp.setOnClickListener(v -> startActivity(new Intent(getApplicationContext(), SignUpActivity.class)));
    }

    private void userSignUp() {

        String email = etEmailLogin.getText().toString().trim();
        String password = etPasswordLogin.getText().toString().trim();

        if (email.isEmpty()) {

            etEmailLogin.setError(getResources().getString(R.string.email_error));
            etEmailLogin.requestFocus();
            return;
        }

        if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {

            etEmailLogin.setError(getResources().getString(R.string.email_doesnt_match));
            etEmailLogin.requestFocus();
            return;
        }

        if (password.isEmpty()) {

            etPasswordLogin.setError(getResources().getString(R.string.password_error));
            etPasswordLogin.requestFocus();
            return;
        }

        if (password.length() < 4) {

            etPasswordLogin.setError(getResources().getString(R.string.password_error_less_than));
            etPasswordLogin.requestFocus();
            return;
        }

        login(email, password);
    }

    private void login(String email, String password) {

        String BASE_URL = "http://10.0.2.2:8040";

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        WebServiceApi api = retrofit.create(WebServiceApi.class);
        Call<List<Profesor>> call = api.login(email, password);

        call.enqueue(new Callback<List<Profesor>>() {
            @Override
            public void onResponse(Call<List<Profesor>> call, Response<List<Profesor>> response) {
                if (response.code() == 200) {
                    Log.d("TAG1", "Profesor logeado");
                } else if (response.code() == 404) {
                    Log.d("TAG1", "Profesor no existe");
                } else {
                    Log.d("TAG1", "Error desconocido");
                }
            }

            @Override
            public void onFailure(Call<List<Profesor>> call, Throwable t) {
                Log.d("TAG Error: ", Objects.requireNonNull(t.getMessage()));
            }
        });

    }
}

这将是我的模范老师:

public class Profesor {

    @SerializedName("id")
    private Long id;
    @SerializedName("nombre")
    private String nombre;
    @SerializedName("email")
    private String email;
    @SerializedName("password")
    private String password;
    @SerializedName("foto")
    private String photo;

    public Profesor(){}

    public Profesor(Long id, String nombre, String email, String photo) {
        this.id = id;
        this.nombre = nombre;
        this.email = email;
        this.photo = photo;
    }

    public Profesor(String email, String password){
        this.email = email;
        this.password = password;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getEmail() {
        return email;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }
}

最后,我对 Retrofit 的调用如下:

@FormUrlEncoded
@POST("api/login")
Call<List<Profesor>> login(@Field("email") String email, @Field("password") String password);

但是,当我运行应用程序并通过表单传递电子邮件和密码时,我在日志中返回“Error desconocido”,但是在 postman 中给了我毫无问题的答案:

postman image

知道我做错了什么吗?

最佳答案

您的 postman 请求不是表单 urlencoded,而是原始请求。 您需要发送 json 作为请求,而不是字段。因此,要解决此问题,您可以更改 API,以处理表单 urlencoded 请求,或以这种方式更改 Android 代码。

public class LoginCredentials {
    @SerializedName("email")
    private String email;
    @SerializedName("password")
    private String password;

    public LoginCredentials(String email, String password) {
        this.email = email;
        this.password = password;
    }
}

并改变这个

@FormUrlEncoded
@POST("api/login")
Call<List<Profesor>> login(@Field("email") String email, @Field("password") String password);

到此

@POST("api/login")
Call<List<Profesor>> login(@Body LoginCredentials credentials);

希望这会有所帮助。

关于java - 使用 Retrofit with Field 传递参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59347620/

相关文章:

android - 使用 GSON 调整 Retrofit 响应

java - 在Eclipse中调试时,是否可以在调试时跳转到某行执行?

java - 你把 super() 调用放在构造函数的开头吗?

Android - 如何设置所有屏幕的背景颜色?

android - 如何在 Retrofit 2.0 中处理分页/加载更多?

java - 失败 : retrofit. RetrofitError : 307 Temporary Redirect?

java - 在 Java 中使用 try catch 的最终实体

java - inDaylightTime() 问题并确定日期是否为夏令时

php - 值在数据库中存储两次

即使在项目中包含 opencv sdk 并添加依赖项后,android 应用程序也会要求安装 OpencvManager