Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

网络访问异常的时候有没有相应的处理方式 #4

Closed
wangran99 opened this issue Aug 14, 2020 · 8 comments
Closed

网络访问异常的时候有没有相应的处理方式 #4

wangran99 opened this issue Aug 14, 2020 · 8 comments

Comments

@wangran99
Copy link

Caused by: com.github.lianjiatech.retrofit.spring.boot.exception.RetrofitExecuteIOException: java.io.IOException: WWWW.XXX.com
HTTP execute fail!Request{method=POST, url=WWW.XXXX.COM

@chentianming11
Copy link
Collaborator

目前,网络访问异常是直接抛出错误。请问下,期望的处理方式大概要什么样子的?

@wangran99
Copy link
Author

网络访问异常是直接抛出错误。请问下,期望的处理方式大概要什么样子的?

有没有默认的exceptionhandler

@chentianming11
Copy link
Collaborator

可以支持,下个版本安排上,谢谢建议~

@chentianming11
Copy link
Collaborator

请问下,你这边使用的场景一般是同步调用,还是异步调用?就是方法返回值类型是普通Java对象较多,还是Call或者CompletableFuture较多?

@wangran99
Copy link
Author

我这边直接返回java对象的同步调用多一些,但是也有个别异步调用返回competefuture,比如后台执行上传文件,但是貌似competefuture返回需要自定义Convert转换器。

@wangran99
Copy link
Author

另外,convert转换器能根据baseurl不同而变化吗,因为不同的服务的返回的数据格式不同,我算是新手,不知道是不是现在就易经实现了,谢谢

@chentianming11
Copy link
Collaborator

1、Retrofit已经支持了competefuture的Convert转换器,不需要自定义再写一个了。
2、convert转换器能根据baseurl不同而变化吗?这个只能通过自定义转换器实现,自定义转换器里面可以拿到调用方法上的注解,这种情况下,可以在接口方法注解上一些信息,然后转换的时候根据注解信息做个性化转化。可以参考以下实现(这个是将请求体的data数据作为返回数据,我们生产上的数据格式要做这个差异化处理,所以也是自定义了转换器):

public class CustomJacksonConverterFactory extends Converter.Factory {

    private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");


    public static CustomJacksonConverterFactory create() {
        return create(new ObjectMapper());
    }

    @SuppressWarnings("ConstantConditions")
    public static CustomJacksonConverterFactory create(ObjectMapper mapper) {
        Assert.notNull(mapper);
        return new CustomJacksonConverterFactory(mapper);
    }

    private final ObjectMapper mapper;

    private CustomJacksonConverterFactory(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                            Retrofit retrofit) {
        return new JacksonResponseBodyConverter<>(type, annotations);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type,
                                                          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        JavaType javaType = mapper.getTypeFactory().constructType(type);
        ObjectWriter writer = mapper.writerFor(javaType);
        return new JacksonRequestBodyConverter<>(writer);
    }

    final class JacksonResponseBodyConverter<T> implements Converter<ResponseBody, T> {

        private Type type;

        private Annotation[] annotations;

        JacksonResponseBodyConverter(Type type, Annotation[] annotations) {
            this.type = type;
            this.annotations = annotations;
        }

        @SuppressWarnings("ConstantConditions")
        public <U> U findAnnotation(Class<U> annotationClass) {
            if (annotations == null) {
                return null;
            }
            if (annotations.length == 0) {
                return null;
            }
            for (Annotation an : annotations) {
                if (annotationClass.equals(an.annotationType())) {
                    return (U) an;
                }
            }
            return null;
        }

        @Override
        public T convert(ResponseBody value) throws IOException {
            JavaType javaType = mapper.getTypeFactory().constructType(type);
            SuccessBody successBody = findAnnotation(SuccessBody.class);
            if (successBody != null) {
                Result result = mapper.readValue(value.charStream(), Result.class);
                int code = result.getCode();
                if (code == successBody.successCode()) {
                    Object data = result.getData();
                    String s = mapper.writeValueAsString(data);
                    if (String.class.getTypeName().equals(type.getTypeName())) {
                        return (T) s;
                    }
                    return mapper.readValue(s, javaType);
                } else {
                    throw new InvalidResponseException(result);
                }
            } else {
                if (String.class.getTypeName().equals(type.getTypeName())) {
                    return (T) value.string();
                }
                return mapper.readValue(value.charStream(), javaType);
            }
        }
    }

    final class JacksonRequestBodyConverter<T> implements Converter<T, RequestBody> {

        private final ObjectWriter adapter;

        JacksonRequestBodyConverter(ObjectWriter adapter) {
            this.adapter = adapter;
        }

        @Override
        public RequestBody convert(T value) throws IOException {
            byte[] bytes = adapter.writeValueAsBytes(value);
            return RequestBody.create(MEDIA_TYPE, bytes);
        }
    }
}

@chentianming11
Copy link
Collaborator

新版本支持errorDecoder,可以实现异常转换处理。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants