背景

最近在做数据需求,根据规则筛选出来一部分item,需要将这些数据用post请求推送给抓取组去异步抓取,为了通用性的考虑采用了写hive udf的方式去做,写udf的过程中遇到了这个编码的问题。

问题和解决

udf的代码长这样:

@Description(name = "http post request with json parameter", value = "_FUNC_(url) - Return null")
public class HttpPostUDF extends UDF {
    private static final Logger logger = LoggerFactory.getLogger(HttpPostUDF.class);
 public String evaluate(String jsonParameter, String url) throws Exception {
        if (null == jsonParameter || null == url || jsonParameter.length() == 0 || url.length() == 0) {
            logger.warn("method must have json parameter and url, and both can not be null or blank");
 return null; }
        return HttpClientUtil.postJson(url, jsonParameter);
 }
}

HttpClientUtil是自己封装的工具类,本次用到的方法是postJson,
一开始的写法是先初始化jsonEntity,再设置编码为UTF-8,打包上线以后发现在数据中有类似"岷江·瑞邦大酒店"这个带有间隔符的数据的时候请求会失败。查看源码发现在初始化StringEntity 对象以后的默认编码是"ISO_5598_1",jsonEntity.setContentEncoding 再去更改编码的时候"·"是识别不了的,所以会出问题。
改成第二种写法,在初始化StringEntity 对象的时候就先设置编码为UTF-8就好了。

public static String postJson(String url, String json) {
    String defaultEncoding = getDefaultEncoding("UTF-8");
 HttpPost post = new HttpPost(url);
 String content = null;
 try {
 //最开始的写法 
 //StringEntity jsonEntity = new StringEntity(json);
 //jsonEntity.setContentEncoding(defaultEncoding);
 //现在的写法
 StringEntity jsonEntity = new StringEntity(json,"UTF-8");
 jsonEntity.setContentType("application/json");
 post.setEntity(jsonEntity);
 content = getClient().execute(post, new CharsetableResponseHandler(defaultEncoding));
 } catch (UnsupportedEncodingException e) {
        throw new RuntimeException("unsupported Encoding " + defaultEncoding, e);
 } catch (Exception e) {
        logger.error(String.format("post [%s] happens error ", url), e);
 } finally {
        post.releaseConnection();
 }
    return content;
}

*参考:
https://blog.csdn.net/wangjin...
https://www.codota.com/code/j...*


nizaikanwome
7 声望0 粉丝

引用和评论

0 条评论