dubbo validation 参数验证 参数校验 @NotNull 自定义响应

使用dubbo 框架 使用 validation 进行参数校验

首先创建类

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.validation.constraints.NotNull;


@Getter
@Setter
@ToString
public class OrderDeductRequestInfo{

   /** 订单号 */
   @JsonProperty(value = "ORDER_NO")
   @NotNull(message = "missing parameter orderNo")
   private String orderNo;

}

 其次创建接口 及 实现

@Path("/test")
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
public interface SuningApi {

    @POST
    @Path("/pay")
    HttpResponseInfo pay(@NotNull(message = "missing request body") OrderDeductRequestInfo info);

}

实现

@Slf4j
@Service(interfaceClass = cn.easysw.bts.suning.controller.api.SuningApi.class,validation = "true")
public class SuningApiImpl implements SuningApi{
   
    @Override
    public HttpResponseInfo pay(OrderDeductRequestInfo info){
        return new HttpResponseInfo("测试");
    }
}

注意创建实现时要开启 service 的 validation 属性

这是注解形式可以 可以使用 xml形式注册实现 开启 validation 属性

此时的 验证已有响应

下面我们进行响应优化做成自己想要的返回数据

 

我的返回实体

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class HttpResponseInfo{

   /**交易状态码,000000 表示成功,非全0表示错误码*/
   @JSONField(name = "RSPCD")
   private String rspcd;

   /**交易描述*/
   @JSONField(name = "RSPMSG")
   private String rspmsg;

   /**响应体,交易定义有返回数据时,数据都在body结点下*/
   @JSONField(name = "BODY")
   private Object body;

   public HttpResponseInfo(Object body){
      this.body=body;
      this.rspcd="000000";
      this.rspmsg="success";
   }
   public HttpResponseInfo(String rspcd,String rspmsg){
      this.body=null;
      this.rspcd=rspcd;
      this.rspmsg=rspmsg;
   }

}

创建dubbo filter


import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.protocol.rest.RpcExceptionMapper;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.lang.reflect.Field;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.constraints.NotNull;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.annotation.XmlElement;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RpcExceptionMapperSupport extends RpcExceptionMapper {
    private static final Logger logger = LoggerFactory.getLogger(RpcExceptionMapper.class);
    WarnExceptionMapper warnExceptionMapper = new WarnExceptionMapper();

    public RpcExceptionMapperSupport() {
    }

    public Response toResponse(RpcException e) {
        FailedResponse faild = null;
        if (e.getCause() instanceof ConstraintViolationException) {
            ConstraintViolationException cve = (ConstraintViolationException)e.getCause();
            ConstraintViolation<?> cv = (ConstraintViolation)cve.getConstraintViolations().iterator().next();
            String message = cv.getMessage();
            if (message != null && message.length() != 0) {
                if (this.isNeedMessageFormat(cv)) {
                    message = this.formatMessage(cv);
                }
            } else {
                message = this.getDefaultMessage(cv);
            }

            faild = new HttpResponseInfo(40001, message);
        } 

        return Response.status(Status.OK).entity(faild).type("application/json; charset=UTF-8").build();
    }

    private boolean isNeedMessageFormat(ConstraintViolation<?> cv) {
        String template = cv.getMessageTemplate();
        String message = cv.getMessage();
        return message.length() > 0 && !message.equals(template) && message.indexOf("{field}") > 0;
    }

    private String formatMessage(ConstraintViolation<?> cv) {
        String message = cv.getMessage();
        String fieldName = this.getFieldName(cv);
        return message.replace("{field}", fieldName);
    }

    private String getDefaultMessage(ConstraintViolation<?> cv) {
        Object annotation = cv.getConstraintDescriptor().getAnnotation();
        if (annotation instanceof NotNull) {
            return "Missing parameter";
        } else {
            return annotation instanceof NotEmpty ? "Empty parameter" : "default";
        }
    }

    private String getFieldName(ConstraintViolation<?> cv) {
        String fieldName = cv.getPropertyPath().toString();

        try {
            Field field = cv.getRootBeanClass().getDeclaredField(fieldName);
            XmlElement xmlAnnotation = (XmlElement)field.getAnnotation(XmlElement.class);
            JsonProperty jsonAnnotation = (JsonProperty)field.getAnnotation(JsonProperty.class);
            if (xmlAnnotation != null && xmlAnnotation.name() != null) {
                return xmlAnnotation.name();
            } else {
                return jsonAnnotation != null && jsonAnnotation.value() != null ? jsonAnnotation.value() : field.getName();
            }
        } catch (SecurityException | NoSuchFieldException var6) {
            var6.printStackTrace();
            return fieldName;
        }
    }
}

接下来在配置中添加

  <dubbo:protocol name="rest" port="${rest.protocol.port}"
                    threads="${rest.protocol.threads}" contextpath="${rest.protocol.contextpath}"
                    server="${rest.protocol.server}" accepts="${rest.protocol.accepts}"
                    serialization="${rest.protocol.serialization}"
                    extension=" cn.webapi.filter.RpcExceptionMapperSupport"/>

这时候返回出来的数据就是我们进行处理过的数据了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值