java使用http post方法提交json数据(不乱码)

问题

  • 需要调用第三方接口发送短信,必须使用post方法,请求和返回都是JSON格式数据,编码要求UTF-8
  • 项目中已有的 HttpUtil 工具类中,有post方法,但是请求此接口没有任何返回;使用curl发送post请求,有数据返回,说明接口没问题
  • 看了下对方接口文档,要求json,应该是需要将json数据放入请求体,只好再加一个post方法了。
  • 重新写了个新方法后,接口能正常访问了。但是新问题来了,中文乱码。明明设置UTF-8,还是不行。下面说下解决方法,并贴上代码。

解决

  • 首先思路要明确,post无数据返回,应该是没遵守对方的接口要求,果断将json格式数据放入请求体,第一个问题解决。
  • 中文乱码,肯定是编码格式问题。虽然设置了UTF-8,但肯定是没设置好。看了下源码,果然是代码写的有问题。
    /**
     * post提交json数据
     * @param url
     * @param json
     * @return
     */
    public static JSONObject doPost(String url, JSONObject json){
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost post = new HttpPost(url);
        JSONObject response = null;
        try {
//            StringEntity s = new StringEntity(json.toString());
//            s.setContentEncoding("UTF-8");
            //上面为乱码出错版本
            StringEntity s = new StringEntity(json.toString(),"UTF-8");
            s.setContentType("application/json");//发送json数据需要设置contentType
            post.setEntity(s);
            HttpResponse res = httpclient.execute(post);
            if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                String result = EntityUtils.toString(res.getEntity());// 返回json格式:
                response = JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        logger.info("执行HTTP Post请求" + url + "时,结果:{}", response);
        return response;
    }

探究

  • 由于短信接口有可信ip限制,必须在服务器上测试,使用curl提交post请求很方便,很实用,需要的可以拿走参考。
curl -H "Content-Type: application/json" -X POST -d '{"senderSystem": "xxx", "authCode":"xxx", "receiverUser":"111", "msgType":"2","content":中文内容" }' "http://xxx:xx/xxx/message/send"
  • 针对乱码问题,主要是StringEntity类的2个不同的构造器,起不同的作用
  • 构造器StringEntity(String string)使用的是默认编码Consts.ISO_8859_1,在new创建对象时,数据已经被转码了,后面再设置UTF-8也没有用了。
  • 构造器StringEntity(String string, String charset)会根据传递的编码格式转码,所以结果符合自己需求。
	//org.apache.http.entity.StringEntity类
	public StringEntity(String string, String charset) throws UnsupportedCharsetException {
        this(string, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
    }
	//使用默认编码
    public StringEntity(String string) throws UnsupportedEncodingException {
        this(string, ContentType.DEFAULT_TEXT);
    }
	// org.apache.http.entity.ContentType类,默认DEFAULT_TEXT 取自TEXT_PLAIN,即 Consts.ISO_8859_1
	static {
        APPLICATION_ATOM_XML = create("application/atom+xml", Consts.ISO_8859_1);
        APPLICATION_FORM_URLENCODED = create("application/x-www-form-urlencoded", Consts.ISO_8859_1);
        APPLICATION_JSON = create("application/json", Consts.UTF_8);
        APPLICATION_OCTET_STREAM = create("application/octet-stream", (Charset)null);
        APPLICATION_SVG_XML = create("application/svg+xml", Consts.ISO_8859_1);
        APPLICATION_XHTML_XML = create("application/xhtml+xml", Consts.ISO_8859_1);
        APPLICATION_XML = create("application/xml", Consts.ISO_8859_1);
        MULTIPART_FORM_DATA = create("multipart/form-data", Consts.ISO_8859_1);
        TEXT_HTML = create("text/html", Consts.ISO_8859_1);
        TEXT_PLAIN = create("text/plain", Consts.ISO_8859_1);
        TEXT_XML = create("text/xml", Consts.ISO_8859_1);
        WILDCARD = create("*/*", (Charset)null);
        DEFAULT_TEXT = TEXT_PLAIN;
        DEFAULT_BINARY = APPLICATION_OCTET_STREAM;
    }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于 HTTP POST 请求,其请求报文包体可能包含请求参数、JSON 数据、XML 数据等多种类型。在 Java 中解析 HTTP POST 请求报文包体的方法也因此而异,下面将分别介绍不同类型请求体的解析方法。 1. 请求参数类型 对于请求参数类型的请求体,可以通过 HttpServletRequest 对象的 getParameter() 方法获取请求参数。在使用方法之前,需要先设置请求体的字符编码为 UTF-8,否则可能会出现中文乱码的情况。 ```java request.setCharacterEncoding("UTF-8"); String param1 = request.getParameter("param1"); String param2 = request.getParameter("param2"); // ... ``` 2. JSON 数据类型 对于 JSON 数据类型的请求体,可以使用 Gson 库将 JSON 数据转化为 Java 对象。在使用 Gson 之前需要先引入该库,可以通过 Maven 或 Gradle 等方式进行引入。 ```java Gson gson = new Gson(); MyObject myObject = gson.fromJson(request.getReader(), MyObject.class); // ... ``` 其中,MyObject 是一个 Java 类,用于表示 JSON 数据。 3. XML 数据类型 对于 XML 数据类型的请求体,可以使用 Java 自带的 SAX 或 DOM 解析器进行解析。以 SAX 解析器为例,其解析过程如下: ```java SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); MyHandler handler = new MyHandler(); parser.parse(request.getInputStream(), handler); MyObject myObject = handler.getMyObject(); // ... ``` 其中,MyHandler 是一个实现了 SAXHandler 接口的 Java 类,用于解析 XML 数据,并将解析结果封装在 MyObject 对象中。 需要注意的是,在使用 SAX 或 DOM 解析器解析 XML 数据时,需要先对 XML 数据进行格式化,以便于解析器能够正确解析。 ```java TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); StreamResult result = new StreamResult(new StringWriter()); DOMSource source = new DOMSource(document); transformer.transform(source, result); String xmlString = result.getWriter().toString(); ``` 在以上代码中,我们使用 DOM 解析器将 XML 数据转化为 Document 对象,并将其格式化为字符串形式。 以上就是 Java 解析 HTTP POST 请求报文包体的基本方法,需要根据不同的请求体类型进行相应的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚持是一种态度

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值