改造 - 使用POST方法调用REST服务

时间:2017-08-21 09:25:31

标签: android retrofit

我第一次使用Retrofit2库使用POST方法进行callin REST API服务时感到困惑。

我试过用Prabeesh(youtube)创建的教程学习。但即使看起来我的API接口逻辑,ApiClient几乎相同,代码也无效。

问题是教程是用GET方法显示的,我不太确定我对POST方法的类比解释是否正确..

使用webbrowser(GET方法)调用服务是成功的,并且创建了用户。 API REST客户端也显示此成功响应(POST方法):

Content-Length: 56
Content-Type: text/html; charset=UTF-8
Date: Mon, 21 Aug 2017 08:18:51 GMT
Server: Apache/2.4.23 (Win64) PHP/5.6.25
X-Powered-By: PHP/5.6.25

对于使用PHP在localhost上创建的REST服务的此请求:

http://localhost/forman/forman/register/newUser/newSurname/geywh@test.com/password/CZE/2017-07-11/1/1/2017-07-12%2000:00:00.000000/2017-07-12%2000:00:00.000000

应该在后端服务上调用index.php中的方法createUser

$app = new \Slim\App;

$app->post('/register/{first_name}/{sur_name}/{email}/{password} /{country}/{birthday}/{fav_driver}/{fav_team}/{created}/{last_login}', function (Request $request, Response $response) {
$first_name = $request->getAttribute('first_name');
$sur_name = $request->getAttribute('sur_name');
$email = $request->getAttribute('email');
$password = $request->getAttribute('password');
$country = $request->getAttribute('country');
$birthday = $request->getAttribute('birthday');
$fav_driver = $request->getAttribute('fav_driver');
$fav_team = $request->getAttribute('fav_team');
$created = $request->getAttribute('created');
$last_login = $request->getAttribute('last_login'); 

$db = new dbhandler();
$res = $db->createUser($first_name, $sur_name, $email, $password, $country, $birthday, $fav_driver, $fav_team, $created, $last_login);

        if ($res == USER_CREATED_SUCCESSFULLY) {
            $response->getBody()->write("Yep, user added!!!!, $first_name $sur_name");
        } else if ($res == USER_CREATE_FAILED) {
            $response->getBody()->write("Error!!!, $first_name $sur_name");
        } 

$response->getBody()->write("Hello, $first_name $sur_name");
return $response;
});
$app->run();
?>

因此,我使用POST方法构建API接口,调用.htaccess中定义的/register站点:

public interface ApiInterface {
@POST("/register")
Call<User> createUser(@Body User user);}

我也在使用带有构造函数,getter,setter的User类以及序列化到REST服务上的字段。

public class User {
//Constructor
public User(String first_name, String sur_name, String email, String password, String country, String birthday, int fav_driver, int fav_team, String created, String last_login) {
}
@SerializedName("first_name")
public String first_name;
@SerializedName("sur_name")
public String sur_name;
@SerializedName("email")
public String email;
@SerializedName("password")
public String password;
@SerializedName("country")
public String country;
@SerializedName("birthday")
public String birthday;
@SerializedName("fav_driver")
public Integer fav_driver;
@SerializedName("fav_team")
public Integer fav_team;
@SerializedName("created")
public String created;
@SerializedName("last_login")
public String last_login;

// Setters
public void setFirst_name(String first_name) {
    this.first_name = first_name;
}
public void setSur_name(String sur_name) {
    this.sur_name = sur_name;
}
public void setEmail(String email) {
    this.email = email;
}
public void setPassword(String password) {
    this.password = password;
}
public void setCountry(String country) {
    this.country = country;
}
public void setBirthday(String birthday) {
    this.birthday = birthday;
}
public void setFav_driver(Integer fav_driver) {
    this.fav_driver = fav_driver;
}
public void setFav_team(Integer fav_team) {
    this.fav_team = fav_team;
}
public void setCreated(String created) {
    this.created = created;
}
public void setLast_login(String last_login) {
    this.last_login = last_login;
}

// Getters
public String getFirst_name() {
    return first_name;
}
public String getSur_name() {
    return sur_name;
}
public String getEmail() {
    return email;
}
public String getPassword() {
    return password;
}
public String getCountry() {
    return country;
}
public String getBirthday() {
    return birthday;
}
public Integer getFav_driver() {
    return fav_driver;
}
public Integer getFav_team() {
    return fav_team;
}
public String getCreated() {
    return created;
}
public String getLast_login() {
    return last_login;
}
}

Api客户端创建改造实例:

public class ApiClient {
public static final String BASE_URL = "http://localhost/forman/forman/";
public static Retrofit retrofit = null;

public static Retrofit getApiClient()  {

    if(retrofit==null) {

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

    }
    return retrofit;
}
}

在我的代码中的onClick方法中调用API接口和API客户端:

public void addButtonClickListener() {
    final Context context = this;

    Button confirm = (Button) findViewById(R.id.bt_save_reg);
    confirm.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {



            TextView firstname = (TextView) findViewById(R.id.editText2);
            String first_name = (String) firstname.getText().toString();

            TextView surname = (TextView) findViewById(R.id.editText3);
            String sur_name = (String) surname.getText().toString();

            TextView email = (TextView) findViewById(R.id.reg_et_email);
            String e_mail = (String) email.getText().toString();

            TextView password = (TextView) findViewById(R.id.etPassword);
            String pass = (String) email.getText().toString();

            TextView country_reg = (TextView) findViewById(R.id.reg_tv_country);
            String country = (String) country_reg.getText().toString();

            TextView birthday_reg = (TextView) findViewById(R.id.birthday_reg);
            String birthday = (String) birthday_reg.getText().toString();

//                TextView fav_driver = (TextView) findViewById(R.id.textView4);
//                Integer favdriver = Integer.valueOf((String) fav_driver.getText().toString());
//
//                TextView fav_team = (TextView) findViewById(R.id.TextViewFavTeam);
//                Integer favteam = Integer.valueOf((String) fav_team.getText().toString());

            User user = new User(first_name, sur_name, e_mail, pass, country, birthday, 1, 1, "2017-07-12 00:00:00.000000", "2017-07-12 00:00:00.000000");

            final ApiInterface apiInterface;

            apiInterface = ApiClient.getApiClient().create(ApiInterface.class);

            Call<User> call = apiInterface.createUser(user);

            call.enqueue(new Callback<User>() {
                @Override
                public void onResponse(Call<User> call, Response<User> response) {

                    Log.d("CREATION", "Check this, because this and    OnFailure never happened!");

                }

                @Override
                public void onFailure(Call<User> call, Throwable throwable) {

                }
            });


        }

    });

}

对不起,对于大量的代码,我是Android,Java,Retrofit的新手..所以,目前我不太确定代码的任何部分。我真的很感激你的帮助,或者我很快就会把子弹放到我脑海里。)

下次,我将学习仅有几个领域的简单模型..

感谢大家检查我的问题,

祝你有愉快的一天, 伊日

2 个答案:

答案 0 :(得分:0)

尝试在改装注释中删除斜杠。你的基本网址最后已经有了斜线。因此,您正在尝试将数据发送到

http://localhost/forman/forman//register

当前代码

@POST("/register")

新代码

@POST("register")

答案 1 :(得分:0)

由于我仍处于困境,我最小化了我的代码(通过创建API测试项目)并提取代码中最重要的组件,以避免一些误解,甚至让你更容易,因为它对我来说还不是很清楚..

我在onCreate活动中调用enqueue方法作为异步请求,以避免手动创建后台线程..

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    User user = new User("John", "Markovicz", "john-markovicz@email.com", "password", "UK", "2017-07-11", 1, 1, "2017-07-12 00:00:00.000000", "2017-07-12 00:00:00.000000" );

    APIInterface apiinterface = APIclient.getClient().create(APIInterface.class);
    Call<User> call = apiinterface.createUser(user);

    call.enqueue(new Callback<User>() {
        @Override
        public void onResponse(Call<User> call, Response<User> response) {
            User result = response.body();
        }

        @Override
        public void onFailure(Call<User> call, Throwable throwable) {
        }
    });
}

如您所见,我想将用户保存在后端数据库中。用户实例是使用User类中定义的构造函数创建的(我希望不需要setter和getter?):

public class User {
public User(String first_name, String sur_name, String email, String password, String country, String birthday, Integer fav_driver, Integer fav_team, String created, String last_login) {
}
}

此界面和我用于将数据设置为后端的此Retrofit实例:

public interface APIInterface {

@POST("register")
Call<User> createUser(@Body User user);
}

改造实例:

public class APIclient {

public static Retrofit getClient() {

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://localhost/forman/forman/")
            .addConverterFactory(GsonConverterFactory.create()).build();
    return retrofit;
}
}

未显示错误。我在设置Android SDK时遇到了一些麻烦,但在安装API 26之后我没有在logcat中收到任何错误。 我通过高级REST客户端测试了一次agin POST方法,并且正确处理了此有效负载请求并存储在DB中:

位置:

http: //localhost/forman/forman/register
Content-Type: application/x-www-form-urlencoded

有效载荷:

first_name=First_name&sur_name=Sur_name&email=Test@gmail.com&password=password&country=CZE&birthday=2017-07-11&fav_driver=1&fav_team=1&created=2017-07-12 00:00:00.000000&last_login=2017-07-12 00:00:00.000000

有没有人有经验来验证我的简单代码?

谢谢你, 伊日