微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WebService接口参数校验实践

最近一直在和WebService打交道,需要接收客户端的请求,解析参数。
一般来说参数可分为系统级参数,和应用级参数。而这些参数又可分为必须和非必须。
举个接口对接来说:
系统级参数有method,sessionKey,format,其中format是可选参数,认为XML,其他为必须参数
应用级参数有fields,pageNo,pageSize,startModified,endModified,其中startModified和endModified是可选,认为”“,而且pageNo和pageSize需要转换为long类型使用

由此进行参数校验至少需要考虑以下情况:
1. 可选参数有没有传递?
2. 参数是否空值?
3. 需要参数强制类型转换时如何防止转换异常(因为像HttpClient传送参数都是以String类型方式传送)
4. 参数认值设置

一般接口都采用HTTP+POST方式,参数都以“key-value”的方式通过“&”连接置于POST请求的Body中:
?method=XXXX&sessionKey=XXXX&fields=XXXX&pageNo=XXXX&pageModifed=XXXX

首先,需要将参数全部获取,并转换到Map中,可以通过一个封装方法处理:

public static Map<String,String> parseRequestString(String str) {
    Map<String,String> parametersMap = new HashMap<String,String>();
    String[] parameters = str.split("&");
    if (parameters.length > 0) {
        for (String parameter : parameters) {
            parametersMap.put(parameter.substring(0,parameter.indexOf("=")),parameter.substring(parameter.indexOf("=") + 1));
        }
    }
    return parametersMap;
}

使用的是@RequestBody 注解,将Body内容当中字符串来处理,也可以使用@RequestParam Map

Map<String,String> parametersMap = parseRequestString(requestString);

String sessionKey;
if (parametersMap.containsKey("sessionKey")) {
    sessionKey = parametersMap.get("sessionKey");
} else {
 return "sessionKey参数不存在";
}
if (sessionKey.length() == 0 || sessionKey.trim().length() == 0 || sessionKey == null) {
 return "sessionKey参数无效";
}

String fields;
if (parametersMap.containsKey("fields")) {
    fields = parametersMap.get("fields");
} else {
 return "fields参数不存在";
}
if (fields.length() == 0 || fields.trim().length() == 0 || fields == null) {
 return "fields参数无效";
}

String pageNoStr;
if (parametersMap.containsKey("pageNo")) {
    pageNoStr = parametersMap.get("pageNo");
} else {
 return "pageNo参数不存在";
}
if (pageNoStr.length() == 0 || pageNoStr.trim().length() == 0 || pageNoStr == null) {
 return "pageNo参数无效";
}
try {
    Long.valueOf(parametersMap.get("pageNo"));
} catch (NumberFormatException e) {
 return "pageNo参数解析为long异常";
}
long pageNo = Long.valueOf(parametersMap.get("pageNo")).longValue();

String pageSizeStr;
if (parametersMap.containsKey("pageSize")) {
    pageSizeStr = parametersMap.get("pageSize");
} else {
 return "pageSize参数不存在";
}
if (pageSizeStr.length() == 0 || pageSizeStr.trim().length() == 0 || pageSizeStr == null) {
 return "pageSize参数无效";
}
try {
    Long.valueOf(parametersMap.get("pageSize").trim());
} catch (NumberFormatException e) {
 return "pageSize参数解析为long异常";
}
long pageSize = Long.valueOf(parametersMap.get("pageSize").trim()).longValue();

String startModified;
if (parametersMap.containsKey("startModified")) {
    startModified = parametersMap.get("startModified");
} else {
 return "startModified参数不存在";
}
if (startModified.length() == 0 || startModified.trim().length() == 0 || startModified == null) {
    startModified = "";
}

String endModified;
if (parametersMap.containsKey("endModified")) {
    endModified = parametersMap.get("endModified");
} else {
 return "endModified参数不存在";
}
if (endModified.length() == 0 || endModified.trim().length() == 0 || endModified == null) {
    endModified = "";
}

上面代码一看就很不舒服,重复代码很多
先抽取一个验证空字符串的方法

public static boolean isEmpty(String str){
        return ( str.length() == 0 || str.trim().length() == 0 || str == null ) 
                    == true ? true : false;
    }

重构:

Map<String,String> parametersMap = parseRequestString(requestString);

String sessionKey;
if (parametersMap.containsKey("sessionKey")) {
    sessionKey = parametersMap.get("sessionKey");
} else {
    return "sessionKey参数不存在";
}
if (isEmpty(sessionKey)) {
    return "sessionKey参数无效";
}
String fields;
if (parametersMap.containsKey("fields")) {
    fields = parametersMap.get("fields");
} else {
    return "fields参数不存在";
}
if (isEmpty(fields)) {
    return "fields参数无效";
}
String pageNoStr;
if (parametersMap.containsKey("pageNo")) {
    pageNoStr = parametersMap.get("pageNo");
} else {
    return "pageNo参数不存在";
}
if (isEmpty(pageNoStr)) {
    return "pageNo参数无效";
}
try {
    Long.valueOf(parametersMap.get("pageNo"));
} catch (NumberFormatException e) {
    return "pageNo参数解析为long异常";
}
long pageNo = Long.valueOf(parametersMap.get("pageNo")).longValue();
String pageSizeStr;
if (parametersMap.containsKey("pageSize")) {
    pageSizeStr = parametersMap.get("pageSize");
} else {
    return "pageSize参数不存在";
}
if (isEmpty(pageSizeStr)) {
    return "pageSize参数无效";
}
try {
    Long.valueOf(parametersMap.get("pageSize").trim());
} catch (NumberFormatException e) {
    return "pageSize参数解析为long异常";
}
long pageSize = Long.valueOf(parametersMap.get("pageSize").trim()).longValue();
String startModified;
if (parametersMap.containsKey("startModified")) {
    startModified = parametersMap.get("startModified");
} else {
    return "startModified参数不存在";
}
if (isEmpty(startModified)) {
    startModified = "";
}
String endModified;
if (parametersMap.containsKey("endModified")) {
    endModified = parametersMap.get("endModified");
} else {
    return "endModified参数不存在";
}
if (isEmpty(startModified)) {
    endModified = "";
}

发现很多参数都在做重复的校验,而且都是通过if 判断 来返回错误消息,可以封装工具类专门用于参数校验

class ParametersCheck {
    private Map<String,String> parametersMap;

    public ParametersCheck(String requestString) {
        parametersMap = new HashMap<String,String>();
        String[] parameters = requestString.split("&");
        if (parameters.length > 0) {
            for (String parameter : parameters) {
                parametersMap.put(parameter.substring(0,parameter.substring(parameter.indexOf("=") + 1));
            }
        }
    }

    public String getString(String key) throws Exception {
        if (!parametersMap.containsKey(key)) {
            throw new NotFoundException(key + " not found");
        }
        if (isEmpty(parametersMap.get(key))) {
            throw new NotFoundException(key + " is Empty");
        }
        return parametersMap.get(key);
    }

    public String getStringOrReplace(String key,String replace) throws Exception {
        if (!parametersMap.containsKey(key)) {
            throw new NotFoundException(key + " not found");
        }

        return isEmpty(parametersMap.get(key)) ? replace : parametersMap.get(key);
    }

    public long getLong(String key) throws Exception {
        if (!parametersMap.containsKey(key)) {
            throw new NotFoundException(key + " not found");
        }
        if (isEmpty(parametersMap.get(key))) {
            throw new NotFoundException(key + " is Empty");
        }
        try {
            Long.valueOf(parametersMap.get(key));
        } catch (NumberFormatException e) {
            throw new RuntimeException(key + " can not format");
        }
        return Long.valueOf(parametersMap.get(key)).longValue();
    }

    public boolean isEmpty(String str) {
        return (str.length() == 0 || str.trim().length() == 0 || str == null) == true ? true : false;
    }
}
ParametersCheck check = new ParametersCheck(requestString);

String sessionKey;
String fields;
String startModified;
String endModified;
long pageNo;
long pageSize;
try {
    sessionKey = check.getString("sessionKey");
    fields = check.getString("fields");
    startModified = check.getStringOrReplace("startModified","");
    endModified = check.getStringOrReplace("endModified","");
    pageNo = check.getLong("pageNo");
    pageSize = check.getLong("pageSize");
} catch (Exception e) {
    return e.getMessage();
}

当然了,优化无止境,经常回过头来看看自己写的代码,你会发现原来,很多代码可以进行优化。对自己的代码优化,其实也是提升自己的能力

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐