简体   繁体   中英

Using @PUT with Retrofit 2 and OkHttp3

Currently, I am using Android with Retrofit 2.0.0-beta4 and OkHttp3. I am doing a @PUT request defined as so:

@Headers({
        Constants.CONTENT_TYPE_HEADER + ": " + Constants.JSON_HEADER_VAL,
        Constants.ACCEPT_HEADER + ": " + Constants.JSON_HEADER_VAL
})
@PUT(Constants.PUT_SKILL_LEVEL)
Call<EmployeeSkill> updateEmpSkillLevel(@Header(Constants.SESSION_COOKIE_NAME) String cookieValue, @Body EmployeeSkillRequest employeeSkillUpdate);

The endpoint goes here: http://apps:8080/employeeSkillsService/employeeSkill . Here is the log output from the PUT request:

D/OkHttp﹕ --> PUT http://apps:8080/employeeSkillsService/employeeSkill http/1.1
D/OkHttp﹕ Content-Type: application/json;charset=UTF-8
D/OkHttp﹕ Content-Length: 99
D/OkHttp﹕ Accept: application/json
D/OkHttp﹕ JSESSIONID: D147377AB60AFE499D2A1AAF7C93F7A3
D/OkHttp﹕ {"employee":{"id":63},"skill":{"isPrimary":false,"isSecondary":false,"id":3},"skillLevel":{"id":5}}
D/OkHttp﹕ --> END PUT (99-byte body)
<-- 404 Not Found http://apps:8080/employeeSkillsService/app.html (23ms)
D/OkHttp﹕ Server: Apache-Coyote/1.1
D/OkHttp﹕ X-Content-Type-Options: nosniff`D/OkHttp﹕ X-XSS-Protection: 1; mode=block`
D/OkHttp﹕ X-XSS-Protection: 1; mode=block
D/OkHttp﹕ Cache-Control: no-cache, no-store, max-age=0, must-revalidate
D/OkHttp﹕ Pragma: no-cache
D/OkHttp﹕ Expires: 0
D/OkHttp﹕ X-Frame-Options: DENY
D/OkHttp﹕ Content-Type: text/html;charset=utf-8
D/OkHttp﹕ Content-Language: en
D/OkHttp﹕ Content-Length: 1029
D/OkHttp﹕ Date: Mon, 07 Mar 2016 15:39:35 GMT
D/OkHttp﹕ OkHttp-Sent-Millis: 1457365206407
D/OkHttp﹕ OkHttp-Received-Millis: 1457365206412
D/OkHttp﹕ <html><head><title>Apache Tomcat/7.0.52 (Ubuntu) - Error report</title><style><!--H1 
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 
{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B{font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 404 - /employeeSkillsService/app.html</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>/employeeSkillsService/app.html</u></p><p><b>description</b> <u>The requested resource is not available.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.52 (Ubuntu)</h3></body></html>
D/OkHttp﹕ <-- END HTTP (1029-byte body)

I have verified in Postman on Chrome that this endpoint with these headers and payload works multiple times. Yet when I use Retrofit I keep receiving a 404 error despite the endpoint working in Postman. Here is the code call:

Call<EmployeeSkill> updateEmployeeSkillCall = RetrofitApiRestClient.getApiClient().updateEmpSkillLevel(cookieValue, employeeSkillUpdate);

updateEmployeeSkillCall.enqueue(new Callback<EmployeeSkill>() {

    @Override
    public void onResponse(Call<EmployeeSkill> call, Response<EmployeeSkill> response) {
        // called when response HTTP status is "200 OK"
        if (response.isSuccess()) {
            holder.spnSkillLevel.setTag(pos);
            Toast.makeText(mContext, holder.tvSkillName.getText() + mContext.getString(R.string.skill_updated_success_text)
                + holder.spnSkillLevel.getSelectedItem().toString(), Toast.LENGTH_LONG).show();

            List<EmployeeSkill> updateEmployeeSkillsRow = EmployeeSkill.find(EmployeeSkill.class, "employee = ? and skill = ?",
                response.body().getEmployee().getId().toString(), response.body().getSkill().getId().toString());

            EmployeeSkill updatedSkill = updateEmployeeSkillsRow.get(0);
            updatedSkill.setSkillLevel(response.body().getSkillLevel());
            updatedSkill.setTimeUpdated(response.body().getSkillLevel().getTimeUpdated());
            updatedSkill.save();
        }
    }

    @Override
    public void onFailure(Call<EmployeeSkill> call, Throwable throwable) {
        Toast.makeText(mContext, holder.tvSkillName.getText() + mContext.getString(R.string.skill_update_failed_text), Toast.LENGTH_LONG).show();
    }
});

I have tried changing the @Body parameter to a JSON String, but I received an error that stated that the JSON must begin with an array or object. Any help in this matter would be useful. Without this functionality, I will be forced to scrap Retrofit if I cannot find a solution and I am not really looking forward to doing that.

Solved my own issue using Fiddler2. Had the cookie name and value incorrect. Postman was probably more forgiving in how it sent things vs. how Retrofit and others did so. Learned something from it, though. Thanks to all who assisted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM