Retrofit2 - 使用正文

时间:2018-01-24 08:49:39

标签: java json retrofit2

我正在使用Retrofit2。 发送带有正文的POST请求(作为JSON数组),但获取“ 400 Bad Request ”。 同时从 SoapUI 发送请求,我的http客户端(基于 HttpURLConnection )正常工作。

服务的API接口:

public interface ApiService {

    @POST( "let/fmir" )
    @Headers( {
            "Accept-Encoding: gzip,deflate",
            "Content-Type: Application/Json;charset=UTF-8",
            "Accept: Application/Json",
            "User-Agent: Retrofit 2.3.0"
    } )
    Call<LetPOJO> fmir(
            @Header( "Authorization" ) String authorization,
            @Body String body
    );
}

API服务提供商:

public class ApiServiceProvider {

    public ApiService createApiService() {
        // Prepare the Retrofit logger
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor( interceptor).build();

        // Build the Retrofit
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl( "http://1.1.1.1:3040/api/v1.0/" )
                .client( client )
                .addConverterFactory( JacksonConverterFactory.create() );
                .build();
        return retrofit.create( ApiService.class );
    }
}

通过声明的API调用服务(输入数据被混淆):

ApiService apiService = ApiServiceProvider.createApiService();
Call<LetPOJO> call = apiService.fmir(
    "Basic NDUhg4234OQ==",
    "[\"L___1\",\"L___2\",\"L___3\",\"L___4\"]"
);

Retrofit拦截器日志:

янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: --> POST http://1.1.1.1:3040/api/v1.0/let/fmir
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: Content-Type: Application/Json;charset=UTF-8
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: Content-Length: 139
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: Accept-Encoding: gzip,deflate
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: Accept: Application/Json
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: User-Agent: Retrofit 2.3.0
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: Authorization: Basic NDUhg4234OQ==
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: 
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: "[\"L___1\",\"L___2\",\"L___3\",\"L___4\"]"
янв 24, 2018 10:12:38 AM okhttp3.internal.platform.Platform log INFO: --> END POST (139-byte body)
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: <-- 400 Bad Request http://1.1.1.1:3040/api/v1.0/let/fmir (121ms)
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: Vary: Accept-Encoding
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: Content-Encoding: gzip
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: Content-Type: text/plain
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: Date: Wed, 24 Jan 2018 07:12:39 GMT
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: Connection: close
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: Content-Length: 192
янв 24, 2018 10:12:39 AM okhttp3.internal.platform.Platform log INFO: <-- END HTTP (encoded body omitted)

响应的内容类型 text / plain ,但预期 Application / Json

例如,使用SoapUI的请求/响应: 请求:

POST http://1.1.1.1:3040/api/v1.0/let/fmir HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json;charset=UTF-8
Authorization: Basic NDUhg4234OQ==
Content-Length: 129
Host: 1.1.1.1:3040
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

及其答复:

HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Type: application/json
Date: Wed, 24 Jan 2018 08:33:12 GMT
Content-Length: 689

[{"id":"L___1"}]

身体也被混淆了。 我们可以看到 Content-Type: application / json

当我通过 HttpURLConnection 发送时 - 请求的HTTP标头也一样,并且工作正常:

  • 授权
  • 内容类型
  • 接受

但是,带有查询的GET请求可以通过Retrofit正常工作。

我没有找到解决此问题的任何方法。在某些情况下,建议使用@Header注释作为方法参数 - 但行为是相同的。

这是服务器端点:

@ApiOperation("Some description") 
@POST @Path("fmir") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
@ApiResponses(value = { 
  @ApiResponse(code = 200, message = "ОК"), 
  @ApiResponse(code = 400, message = "some message"), 
  @ApiResponse(code = 500, message = "some message") 
}) 
public List<Letter> getLet(
    @ApiParam(value = "Authorization header") 
    @HeaderParam(HttpHeaders.AUTHORIZATION) final String authorization, 
    @Context ContainerRequestContext context, 
    final List<String> letterIds) {
  // ...
}

1 个答案:

答案 0 :(得分:1)

由于服务器端点需要一个字符串列表,我认为您的客户端也需要发送它(不发送字符串):

所以,试试这个:

public interface ApiService {

    @POST( "let/fmir" )
    @Headers( {
            "Accept-Encoding: gzip,deflate",
            "Content-Type: Application/Json;charset=UTF-8",
            "Accept: Application/Json",
            "User-Agent: Retrofit 2.3.0"
    } )
    Call<LetPOJO> fmir(
            @Header( "Authorization" ) String authorization,
            @Body List<String> body
    );
}

...

ApiService apiService = ApiServiceProvider.createApiService();
Call<LetPOJO> call = apiService.fmir(
    "Basic NDUhg4234OQ==",
    Arrays.asList("L___1", "L___2", "L___3", "L___4")
);