sofastack / sofa-rpc-boot-projects

SOFABoot projects for SOFARPC, include starter and samples.
https://github.com/sofastack/sofa-rpc
Apache License 2.0
292 stars 117 forks source link

api方式引用带有数据校验的接口抛异常 #72

Closed qinliang373 closed 6 years ago

qinliang373 commented 6 years ago

Your question

describe your question clearly sofaboot服务端发布带有数据校验的服务,在客户端以api方式引用抛异常。 服务端接口 @POST @Path("/verify") public Result verify(@Valid IdCardVerifyRequest idCardVerifyRequest); 全局数据验证异常处理 public class SimpleValidationExceptionMapper implements ExceptionMapper {

public static final Logger logger = LoggerFactory.getLogger(SimpleValidationExceptionMapper.class);

/* (non-Javadoc)
 * @see javax.ws.rs.ext.ExceptionMapper#toResponse(java.lang.Throwable)
 */
@Override
public Response toResponse(ResteasyViolationException exception) {
    List<String> list = new ArrayList<String>();
    Set<ConstraintViolation<?>> set = exception.getConstraintViolations();
    for(ConstraintViolation<?> cv : set) {
        list.add(cv.getMessage());
    }

    logger.warn("数据验证失败:{}",JSON.toJSONString(list));

    int code = Integer.parseInt(CodeMsgEnum.VALIDATE_FAILURE.getCode());
    return Response.status(code).entity(list).build();
}

} 客户端引用 ConsumerConfig consumerConfig = new ConsumerConfig() .setInterfaceId(IdCardVerifyFacade.class.getName()) // 指定接口 .setProtocol("rest") // 指定协议 .setDirectUrl("rest://88.251.24.187:9999")// .setConnectTimeout(2000); // 指定直连地址

    IdCardVerifyFacade f = consumerConfig.refer();

    IdCardVerifyRequest r = new IdCardVerifyRequest();
    r.setName("");
    r.setIdCard("");
    Result<IdCardVerify> result = f.verify(r);
    System.out.println(JSON.toJSONString(result));

运行结果 Exception in thread "main" com.alipay.sofa.rpc.core.exception.SofaRpcException: Send message to remote catch error: HTTP 409 Conflict at com.alipay.sofa.rpc.transport.AbstractProxyClientTransport.convertToRpcException(AbstractProxyClientTransport.java:233) at com.alipay.sofa.rpc.transport.AbstractProxyClientTransport.syncSend(AbstractProxyClientTransport.java:156) at com.alipay.sofa.rpc.client.AbstractCluster.doSendMsg(AbstractCluster.java:509) at com.alipay.sofa.rpc.client.AbstractCluster.sendMsg(AbstractCluster.java:480) at com.alipay.sofa.rpc.filter.ConsumerInvoker.invoke(ConsumerInvoker.java:60) at com.alipay.sofa.rpc.filter.RpcReferenceContextFilter.invoke(RpcReferenceContextFilter.java:80) at com.alipay.sofa.rpc.filter.FilterInvoker.invoke(FilterInvoker.java:96) at com.alipay.sofa.rpc.filter.ConsumerExceptionFilter.invoke(ConsumerExceptionFilter.java:37) at com.alipay.sofa.rpc.filter.FilterInvoker.invoke(FilterInvoker.java:96) at com.alipay.sofa.rpc.filter.FilterChain.invoke(FilterChain.java:299) at com.alipay.sofa.rpc.client.AbstractCluster.filterChain(AbstractCluster.java:473) at com.alipay.sofa.rpc.client.FailoverCluster.doInvoke(FailoverCluster.java:66) at com.alipay.sofa.rpc.client.AbstractCluster.invoke(AbstractCluster.java:286) at com.alipay.sofa.rpc.client.ClientProxyInvoker.invoke(ClientProxyInvoker.java:83) at com.alipay.sofa.rpc.proxy.jdk.JDKInvocationHandler.invoke(JDKInvocationHandler.java:75) at com.sun.proxy.$Proxy22.verify(Unknown Source) at com.mfbank.service.MainC.main(MainC.java:40) Caused by: javax.ws.rs.ClientErrorException: HTTP 409 Conflict at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:216) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:174) at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:58) at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:104) at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:62) at com.sun.proxy.$Proxy22.verify(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.alipay.sofa.rpc.transport.AbstractProxyClientTransport.doInvokeSync(AbstractProxyClientTransport.java:183) at com.alipay.sofa.rpc.transport.AbstractProxyClientTransport.syncSend(AbstractProxyClientTransport.java:154) ... 15 more

Your scenes

describe your use scenes (why need this feature)

Your advice

describe the advice or solution you'd like

Environment

com.alipay.sofa sofa-rpc-all 5.3.2 com.alibaba fastjson 1.2.0
<dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.4</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.3.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
       <version>4.3.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
       <version>4.3.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.0</version>
    </dependency>
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

leizhiyuan commented 6 years ago

能提供一个可以复现的 demo 么?

qinliang373 commented 6 years ago

服务端provider @Path(Constants.CONTEXT_PATH + "/creditReportFacade") @Produces(MediaTypes.JSON_UTF_8) @Consumes(MediaTypes.JSON_UTF_8) public interface CreditReportFacade { /**

=================================================== 服务端实现 public class CreditReportServiceImpl implements CreditReportFacade{

private static final Logger logger = LoggerFactory.getLogger(CreditReportServiceImpl.class);

public Result<CreditReport> getCreditReport(CreditReportRequest creditReportRequest) {

    Result<CreditReport> result = new Result<CreditReport>();

    result.setSuccess(true);
    result.setCode(CodeMsgEnum.SUCCESS.getCode());
    result.setMessage(CodeMsgEnum.SUCCESS.getDesc());

    return result;
}

}

======================================== /**

======================================================= 客户端consume 客户端引用 ConsumerConfig consumerConfig = new ConsumerConfig() .setInterfaceId(IdCardVerifyFacade.class.getName()) // 指定接口 .setProtocol("rest") // 指定协议 .setDirectUrl("rest://ip+port")// .setConnectTimeout(2000); IdCardVerifyFacade f = consumerConfig.refer();
IdCardVerifyRequest r = new IdCardVerifyRequest(); r.setName(""); r.setIdCard(""); Result result = f.verify(r); System.out.println(JSON.toJSONString(result)); 代码就这样

leizhiyuan commented 6 years ago

你这个代码和你的项目耦合太多,方便的话,可以fork 下 rpc 工程,

com.alipay.sofa.rpc.rest.start.RestClientMain 在这个example 的基础上改下来描述你的问题.

qinliang373 commented 6 years ago

哦,我的也没逻辑。就是服务端发布rest协议(校验失败采用异常统一处理),在浏览器下访问校验失败显示校验失败原因。采用api访问就抛莫名其妙的异常了。

qinliang373 commented 6 years ago

去掉统一异常处理,采用api方式访问就可以正常请求了