Capotasto
Capotasto

Reputation: 131

How to solve the IllegalArgumentException "Malformed content type: ......" with Retrofit

I have been tested speech recognition API by Microsoft for getting the String from a short audio file. This API needs none well-formed media type (Is this really none well-formed? for only Retrofit or Okhttp?).

Content-Type: audio/wav; codec=audio/pcm; samplerate=16000

So I set it for the Retrofit interface like below.

 @Multipart
    @POST("/speech/recognition/{recognitionMode}/cognitiveservices/v1")
    Observable<Recognition> getRecgnition(
            @Header("Ocp-Apim-Subscription-Key") String subscriptionKey,
            @Header("Content-Type") String contentType,
            @Path("recognitionMode") String recognitionMode,
            @Query("language") String language,
            @Query("format") String format,
            @Part("file")RequestBody file
    );

Then I have got the error in the request to send an audio file with this header. I know the reason because MediaType#parse is going to return null because Matcher#lookingAt is going to return false.

Okay, I got the reason. but I don't know how to ignore this exception. Could you please give me some advice to avoid this error?

java.lang.IllegalArgumentException: Malformed content type: audio/wav;codec=audio/pcm; samplerate=16000
     at retrofit2.RequestBuilder.addHeader(RequestBuilder.java:81)
     at retrofit2.ParameterHandler$Header.apply(ParameterHandler.java:79)
     at retrofit2.ServiceMethod.toRequest(ServiceMethod.java:111)
     at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:184)
     at retrofit2.OkHttpCall.execute(OkHttpCall.java:168)
     at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:40)
     at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:24)
     at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:36)
     at retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:28)
     at rx.Observable.unsafeSubscribe(Observable.java:10256)
     at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)
     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
     at java.lang.Thread.run(Thread.java:762)

Upvotes: 2

Views: 3777

Answers (1)

Capotasto
Capotasto

Reputation: 131

I have just found the solution to this problem. Just added headers with Okhttp intercepter.

private class SpeechRecognitionIntercepter implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Headers.Builder builder = new Headers.Builder();
        builder.add("Ocp-Apim-Subscription-Key", "here-is-your-own-subscription-key");
        builder.add("Accept", "application/json");
        builder.add("Content-Type", "audio/wav; codec=audio/pcm; samplerate=16000");
        return chain.proceed(
                chain.request().newBuilder()
                        .headers(builder.build())
                        .build()
        );
    }
}

Then add this intercepter.

new OkHttpClient.Builder().addInterceptor(new SpeechRecognitionIntercepter())

Upvotes: 1

Related Questions