Retrofit - removing some invalid characters from response body before parsing it as json

后端 未结 4 2125
旧巷少年郎
旧巷少年郎 2020-12-30 09:58

I have an external web service that in the response body returns json but nested in parentheses, like this:

({\"door_x\":\"103994.001461\",\"door_y\":\"98780         


        
4条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-30 10:40

    You can clean painlessly the response in your GsonConverter before Gson deserialized the body into type object.

     public class CleanGsonConverter extends GsonConverter{
    
                public CleanGsonConverter(Gson gson) {
                    super(gson);
                }
    
                public CleanGsonConverter(Gson gson, String encoding) {
                    super(gson, encoding);
                }
    
                @Override
                public Object fromBody(TypedInput body, Type type) throws ConversionException {
                    String dirty = toString(body);
                    String clean = dirty.replaceAll("(^\\(|\\)$)", "");
                    body = new JsonTypedInput(clean.getBytes(Charset.forName(HTTP.UTF_8)));
                    return super.fromBody(body, type);
                }
                private String toString(TypedInput body){
                        BufferedReader br = null;
                        StringBuilder sb = new StringBuilder();
                        String line;
                        try {
                            br = new BufferedReader(new InputStreamReader(body.in()));
                            while ((line = br.readLine()) != null) {
                                sb.append(line);
                            }
    
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            if (br != null) {
                                try {
                                    br.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
    
                        return sb.toString();
    
                    }
            };
    

    JsonTypedInput:

       public class JsonTypedInput implements TypedInput{
    
            private final byte[] mStringBytes;
    
            JsonTypedInput(byte[] stringBytes) {
                this.mStringBytes = stringBytes;
            }
    
    
            @Override
            public String mimeType() {
                return "application/json; charset=UTF-8";
            }
    
    
    
            @Override
            public long length() {
                return mStringBytes.length;
            }
    
            @Override
            public InputStream in() throws IOException {
                return new ByteArrayInputStream(mStringBytes);
            }
        }
    

    Here I subclassed GsonConverter to get access to the response before it is converted to object. JsonTypedOutput is used to preserve the mime type of the response after cleaning it from the junk chars.

    Usage:

    restAdapterBuilder.setConverter(new CleanGsonConverter(gson));

    Blame it on your backend guys. :)

提交回复
热议问题