背景
最近在做数据需求,根据规则筛选出来一部分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...*
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。