您的位置:首页 > 理论基础 > 计算机网络

HttpURLConnection用法详解

2016-12-27 15:52 375 查看
微信开发的时候,经常遇到weixinUtil.java 类和CommonUtil.java类,但是很多的博客都没有给出这两个类,我也是很纠结,现将CommonUtil.java类的讲解给大家,但是亲测是不能成功的(后面会将这两个类的具体代码分享给大家,是可行的哟!)

针对JDK中的URLConnection连接Servlet的问题,网上有虽然有所涉及,但是只是说明了某一个或几个问题,是以FAQ的方式来解决的,而且比较零散,现在对这个类的使用就本人在项目中的使用经验做如下总结:

1:> URL请求的类别:

分为二类,GET与POST请求。二者的区别在于:

a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,

b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

2:> URLConnection的对象问题:

URLConnection的对象,如下代码示例:

// 下面的index.jsp由映射到

// 一个Servlet(com.quantanetwork.getClientDataServlet)

// 该Servlet的注意点下边会提到
URL url = new URL("http://localhost:8080/TestHttpURLConnectionPro/index.jsp");

URLConnection rulConnection = url.openConnection();
// 此处的urlConnection对象实际上是根据URL的
// 请求协议(此处是http)生成的URLConnection类
// 的子类HttpURLConnection,故此处最好将其转化
// 为HttpURLConnection类型的对象,以便用到
// HttpURLConnection更多的API.如下:

HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection;
1
2
3
4
5
6
7
8
9
10
[/code]

3:> HttpURLConnection对象参数问题
// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true, 默认情况下是false;
httpUrlConnection.setDoOutput(true);

// 设置是否从httpUrlConnection读入,默认情况下是true;
httpUrlConnection.setDoInput(true);

// Post 请求不能使用缓存
httpUrlConnection.setUseCaches(false);

// 设定传送的内容类型是可序列化的java对象
// (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");

// 设定请求的方法为"POST",默认是GET
httpUrlConnection.setRequestMethod("POST");

// 连接,从上述第2条中url.openConnection()至此的配置必须要在connect之前完成,
httpUrlConnection.connect();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[/code]

4:> HttpURLConnection连接问题:
// 此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,
// 所以在开发中不调用上述的connect()也可以)。
OutputStream outStrm = httpUrlConnection.getOutputStream();
1
2
3
4
[/code]

5:> HttpURLConnection写数据与发送数据问题:
1 // 现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。
2  ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm);
3
4  // 向对象输出流写出数据,这些数据将存到内存缓冲区中
5  objOutputStrm.writeObject(new String("我是测试数据"));
6
7  // 刷新对象输出流,将任何字节都写入潜在的流中(些处为ObjectOutputStream)
8  objOutputStm.flush();
9
10  // 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,
11  // 在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器
12  objOutputStm.close();
13
14  // 调用HttpURLConnection连接对象的getInputStream()函数,
15  // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。
16  InputStream inStrm = httpConn.getInputStream(); // <===注意,实际发送请求的代码段就在这里
17
18  // 上边的httpConn.getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的输出已无意义,
19  // 既使对象输出流没有调用close()方法,下边的操作也不会向对象输出流写入任何数据.
20  // 因此,要重新发送数据时需要重新创建连接、重新设参数、重新创建流对象、重新写数据、
21  // 重新发送数据(至于是否不用重新这些操作需要再研究)
22  objOutputStm.writeObject(new String(""));
23 httpConn.getInputStream()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[/code]

总结:a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。
b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,
对connection对象的一切配置(那一堆set函数)
都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。
这些顺序实际上是由http请求的格式决定的。
如果inputStream读操作在outputStream的写操作之前,会抛出例外:
java.net.ProtocolException: Cannot write output after reading input.......

c:) http请求实际上由两部分组成,
一个是http头,所有关于此次http请求的配置都在http头里面定义,
一个是正文content。
connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,
就必须把所有的配置准备好。
d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,
实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,
而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。
至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求
正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http
请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数
之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)
都是没有意义的了,执行这些操作会导致异常的发生。


6:> Servlet端的开发注意点:

a:) 对于客户端发送的POST类型的HTTP请求,Servlet必须实现doPost方法,而不能用doGet方法。

b:) 用HttpServletRequest的getInputStream()方法取得InputStream的对象,比如:

InputStream inStream = httpRequest.getInputStream();

现在调用inStream.available()(该方法用于“返回此输入流下一个方法调用可以不受阻塞地

从此输入流读取(或跳过)的估计字节数”)时,永远都反回0。试图使用此方法的返回值分配缓冲区,

以保存此流所有数据的做法是不正确的。那么,现在的解决办法是

Servlet这一端用如下实现:

InputStream inStream = httpRequest.getInputStream();

ObjectInputStream objInStream = new ObjectInputStream(inStream);

Object obj = objInStream.readObject();

// 做后续的处理

// 。。。。。。

// 。。。 。。。

而客户端,无论是否发送实际数据都要写入一个对象(那怕这个对象不用),如:

ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm);

objOutputStrm.writeObject(new String(“”)); // 这里发送一个空数据

// 甚至可以发一个null对象,服务端取到后再做判断处理。

objOutputStrm.writeObject(null);

objOutputStrm.flush();

objOutputStrm.close();

注意:上述在创建对象输出流ObjectOutputStream时,如果将从HttpServletRequest取得的输入流

(即:new ObjectOutputStream(outStrm)中的outStrm)包装在BufferedOutputStream流里面,

则必须有objOutputStrm.flush();这一句,以便将流信息刷入缓冲输出流.如下:

ObjectOutputStream objOutputStrm = new ObjectOutputStream(new BufferedOutputStream(outStrm));

objOutputStrm.writeObject(null);

objOutputStrm.flush(); // <======此处必须要有.

objOutputStrm.close();

HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时:

System.setProperty(“sun.net.client.defaultConnectTimeout”, 超时毫秒数字符串);

System.setProperty(“sun.net.client.defaultReadTimeout”, 超时毫秒数字符串);

其中: sun.net.client.defaultConnectTimeout:连接主机的超时时间(单位:毫秒)

sun.net.client.defaultReadTimeout:从主机读取数据的超时时间(单位:毫秒)

例如:

System.setProperty(“sun.net.client.defaultConnectTimeout”, “30000”);

System.setProperty(“sun.net.client.defaultReadTime

Java中可以使用HttpURLConnection来请求WEB资源。

HttpURLConnection对象不能直接构造,需要通过URL.openConnection()来获得HttpURLConnection对象,示例代码如下:

1 String szUrl = “http://www.ee2ee.com/“;

2 URL url = new URL(szUrl);

3 HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();

HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时:

System.setProperty(“sun.net.client.defaultConnectTimeout”, 超时毫秒数字符串);

System.setProperty(“sun.net.client.defaultReadTimeout”, 超时毫秒数字符串);

其中: sun.net.client.defaultConnectTimeout:连接主机的超时时间(单位:毫秒)

sun.net.client.defaultReadTimeout:从主机读取数据的超时时间(单位:毫秒)

例如:

System.setProperty(“sun.net.client.defaultConnectTimeout”, “30000”);

System.setProperty(“sun.net.client.defaultReadTimeout”, “30000”);

JDK 1.5以前的版本,只能通过设置这两个系统属性来控制网络超时。在1.5中,还可以使用HttpURLConnection的父类URLConnection的以下两个方法:

setConnectTimeout:设置连接主机超时(单位:毫秒)

setReadTimeout:设置从主机读取数据超时(单位:毫秒)

例如:

1 HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();

2 urlCon.setConnectTimeout(30000);

3 urlCon.setReadTimeout(30000);

需要注意的是,笔者在JDK1.4.2环境下,发现在设置了defaultReadTimeout的情况下,如果发生网络超时,HttpURLConnection会自动重新提交一次请求,出现一次请求调用,请求服务器两次的问题(Trouble)。我认为这是JDK1.4.2的一个bug。在JDK1.5.0中,此问题已得到解决,不存在自动重发现象。out”, “3000

WeixinUtil.java
package com.gson.templateMessage;

/**
* Created by Administrator on 2016/8/5.
*/

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* 项目名称:wechatapi
* 类名称:WeixinUtil
* 类描述:微信基础类
* 创建人:WQ
* 创建时间:2014-1-18 下午4:05:11
* @version
*/
public class WeixinUtil {
// 日志文件
protected final static Logger log = LoggerFactory.getLogger(WeixinUtil.class);

// 接收消息类型:文本
public final static String RECRIVE_TEXT = "text";
// 接收消息类型:图片
public final static String RECRIVE_IMAGE = "image";
// 接收消息类型:语音
public final static String RECRIVE_VOICE = "voice";
// 接收消息类型:视频
public final static String RECRIVE_VIDEO = "video";
// 接收消息类型:地理位置
public final static String RECRIVE_LOCATION = "location";
// 接收消息类型:链接
public final static String RECRIVE_LINK = "link";
// 接收消息类型:推送
public final static String RECRIVE_EVENT = "event";

// 回复消息类型:文本
public final static String REQUEST_TEXT = "text";
// 回复消息类型:图片
public final static String REQUEST_IMAGE = "image";
// 回复消息类型:语音
public final static String REQUEST_VOICE = "voice";
// 回复消息类型:视频
public final static String REQUEST_VIDEO = "video";
// 回复消息类型:音乐
public final static String REQUEST_MUSIC = "music";
// 回复消息类型:图文
public final static String REQUEST_NEWS = "news";

// 事件类型:subscribe(订阅)
public final static String EVENT_SUBSCRIBE = "subscribe";
// 事件类型:unsubscribe(取消订阅)
public final static String EVENT_UNSUBSCRIBE = "unsubscribe";
// 事件类型:LOCATION(上报地理位置事件)
public final static String EVENT_LOCATION = "LOCATION";
// 事件类型:CLICK(自定义菜单点击事件)
public final static String EVENT_CLICK = "CLICK";

/**
* 扫描带参数二维码事件
* 用户扫描带场景值二维码时,可能推送以下两种事件:
1.如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
2.如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。
*/
// 事件类型:subscribe(用户未关注时,进行关注后的事件推送)
public final static String EVENT_QRCODE_SUBSCRIBE = "subscribe";
// 事件类型:scan(用户已关注时的事件推送)
public final static String EVENT_QRCODE_SCAN = "scan";

// 获取access_token的接口地址(GET) 限200(次/天)
public final static String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// 开发者可通过OpenID来获取用户基本信息 url
protected final static String GET_PERSONALINF_URL="https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
// 通过OpenID获取查询用户所在分组url
protected final static String GET_PERSONGROUPID_URL="https://api.weixin.qq.com/cgi-bin/groups/getid?access_token=ACCESS_TOKEN";
/**
*  OAuth2.0引导关注者打开 用户同意授权,获取code页面url
*  1.scope的设置为:snsapi_base(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面)
*  2.redirect_uri:授权后重定向的回调链接地址,请使用urlencode对链接进行处理  方法再commonutil的urlEncodeUTF8()
*/
public final static String FANS_GET_CODE="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
// OAuth2.0通过code换取网页授权access_token
protected final static String OAUTH2_ACCESSTOKEN_URL="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
// OAuth2.0刷新access_token
protected final static String REFRESH_ACCESSTOKEN_URL="https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
// OAuth2.0拉取用户信息(需scope为 snsapi_userinfo)
protected final static String OAUTH2_USERINFO_URL="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
// 主动发送客服消息url
protected final static String SEND_CUSTOM_URL="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
// 生成临时二维码url
protected final static String TEMPORARY_QRCODE_URL="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";
// 生成永久二维码url
protected final static String PERMANENT_QRCODE_URL="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";
// 换取二维码url
protected final static String GET_QRCODE_URL="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
// 获取关注者列表url
protected final static String GET_USERLIST_URL="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";

// 获取所有分组信息url
protected final static String GET_GROUPS_URL="https://api.weixin.qq.com/cgi-bin/groups/get?access_token=ACCESS_TOKEN";
// 创建分组url
protected final static String CREATE_GROUPS_URL="https://api.weixin.qq.com/cgi-bin/groups/create?access_token=ACCESS_TOKEN";
// 修改分组url
protected final static String UPDATE_GROUPS_URL="https://api.weixin.qq.com/cgi-bin/groups/update?access_token=ACCESS_TOKEN";
// 移动用户分组url
protected final static String REMOVE_MEMBER_URL="https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token=ACCESS_TOKEN";

// 上传多媒体文件url
protected final static String UPLOAD_MEDIA_URL="http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
// 下载多媒体文件url
protected final static String DOWNLOAD_MEDIA_URL="http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";

// 菜单创建(POST) 限100(次/天)
protected final static String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
// 菜单查询(GET)
protected final static String GET_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
// 菜单删除(GET)
protected final static String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
[/code]

CommonUtil.java
package com.gson.templateMessage;

/**
* Created by Administrator on 2016/8/5.
*/

import com.gson.bean.AccessToken;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLEncoder;

/**
*
* 项目名称:wechatsapi
* 类名称:CommonUtil
* 类描述:http请求和接收
* 创建人:WQ
* 创建时间:2014-1-26 下午7:34:54
* @version
*/
public class CommonUtil extends WeixinUtil{
/**
* 发起https请求并获取结果
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject (通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
//创建SSLContext对象,并使用我们指定的信任管理器初始化(证书过滤)
TrustManager[] tm = { new MyX509TrustManager() };
//取得SSL的SSLContext实例
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
//初始化SSLContext
sslContext.init(null, tm, new java.security.SecureRandom());
//从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn=(HttpsURLConnection) url.openConnection();
System.out.println("httpUrlConn++++++++++++++++++++"+httpUrlConn);
httpUrlConn.setSSLSocketFactory(ssf);

httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
//设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);

/*if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();*/
//当有数据需要提交时(当outputStr不为null时,向输出流写数据)
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.flush();
outputStream.close();
System.out.println("outputStream++++++++++++++"+outputStream);
}

// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
System.out.println("inputStream++++++++++++++++++"+inputStream);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.println("bufferedReader++++++++++++++++++"+bufferedReader);
/*System.out.println("bufferedReader.read()++++++++++++++++++"+bufferedReader.read());*/
/*System.out.println("bufferedReader.readLine()++++++++++++++++++"+bufferedReader.readLine());*/
String str = null;
StringBuffer buffer=new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
System.out.println("str+++++++++++++"+str);
buffer.append(str);
}
/* buffer.append(bufferedReader.read());*/

//释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
System.out.println("buffer++++++++++++++++++"+buffer.toString());
httpUrlConn.disconnect();
jsonObject=JSONObject.fromObject(buffer.toString());
System.out.println("jsonObject+++++++++++++"+jsonObject);

} catch (ConnectException ce) {
log.error("连接超时: {}",ce);
} catch (Exception e) {
log.error("https请求异常: {}", e);
}
return jsonObject;
}

/**
* 获取access_token
*
* @param appid 凭证  wx13c0a227486f7e64
* @param appsecret 密钥 864e16284d38c05c62cddc1be000351e
* @return AccessToken 返回接口凭证
*/
public static String getAccessToken(String appid, String appsecret) {
AccessToken accessToken=new AccessToken();
String requestUrl = GET_ACCESS_TOKEN_URL.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET",null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken.setAccesstoken(jsonObject.getString("access_token"));
accessToken.setExpiresin(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return accessToken.getAccesstoken().toString();
}

/**
* URL编码(utf-8)
*
* @param source
* @return String
*/
public static String urlEncodeUTF8(String source) {
String result=source;
try {
result=URLEncoder.encode(source, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}

/**
* 根据类型判断文件扩展名
*
* @param contentType 内容类型
* @return String
*/
public static String getFileExt(String contentType) {
String fileExt="";
if ("image/jpeg".equals(contentType)) {
fileExt=".jpg";
}else if ("audio/mpeg".equals(contentType)) {
fileExt=".mp3";
}else if ("audio/amr".equals(contentType)) {
fileExt=".amr";
}else if ("video/mp4".equals(contentType)) {
fileExt=".mp4";
}else if ("video/mpeg4".equals(contentType)) {
fileExt=".mp4";
}
return fileExt;
}

public static void Main() {
/*String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx13c0a227486f7e64&redirect_uri=http%3A%2F%2F122.228.158.111%2FTest%2Fservlet%2FOAuthServlet&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";*/

String url="http://122.228.158.111/Test/servlet/OAuthServlet";
System.err.println(urlEncodeUTF8(url));

// 获取接口访问凭证
/*AccessToken accessToken=getAccessToken("wx801484513be0eea4", "95441812e081c1ac6cc17dc62023f245");*/
/* if (accessToken.getAccesstoken()==null) {
System.out.println("空");
}else {
System.out.println(accessToken.getAccesstoken());
}*/
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
[/code]



版权声明:本文为博主原创文章,未经博主允许不得转载。


顶0 踩0

微信开发的时候,经常遇到weixinUtil.java 类和CommonUtil.java类,但是很多的博客都没有给出这两个类,我也是很纠结,现将CommonUtil.java类的讲解给大家,但是亲测是不能成功的(后面会将这两个类的具体代码分享给大家,是可行的哟!)

针对JDK中的URLConnection连接Servlet的问题,网上有虽然有所涉及,但是只是说明了某一个或几个问题,是以FAQ的方式来解决的,而且比较零散,现在对这个类的使用就本人在项目中的使用经验做如下总结:

1:> URL请求的类别:

分为二类,GET与POST请求。二者的区别在于:

a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,

b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

2:> URLConnection的对象问题:

URLConnection的对象,如下代码示例:

// 下面的index.jsp由映射到

// 一个Servlet(com.quantanetwork.getClientDataServlet)

// 该Servlet的注意点下边会提到
URL url = new URL("http://localhost:8080/TestHttpURLConnectionPro/index.jsp");

URLConnection rulConnection = url.openConnection();
// 此处的urlConnection对象实际上是根据URL的
// 请求协议(此处是http)生成的URLConnection类
// 的子类HttpURLConnection,故此处最好将其转化
// 为HttpURLConnection类型的对象,以便用到
// HttpURLConnection更多的API.如下:

HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection;
1
2
3
4
5
6
7
8
9
10
[/code]

3:> HttpURLConnection对象参数问题
// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true, 默认情况下是false;
httpUrlConnection.setDoOutput(true);

// 设置是否从httpUrlConnection读入,默认情况下是true;
httpUrlConnection.setDoInput(true);

// Post 请求不能使用缓存
httpUrlConnection.setUseCaches(false);

// 设定传送的内容类型是可序列化的java对象
// (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");

// 设定请求的方法为"POST",默认是GET
httpUrlConnection.setRequestMethod("POST");

// 连接,从上述第2条中url.openConnection()至此的配置必须要在connect之前完成,
httpUrlConnection.connect();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[/code]

4:> HttpURLConnection连接问题:
// 此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,
// 所以在开发中不调用上述的connect()也可以)。
OutputStream outStrm = httpUrlConnection.getOutputStream();
1
2
3
4
[/code]

5:> HttpURLConnection写数据与发送数据问题:
1 // 现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。
2  ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm);
3
4  // 向对象输出流写出数据,这些数据将存到内存缓冲区中
5  objOutputStrm.writeObject(new String("我是测试数据"));
6
7  // 刷新对象输出流,将任何字节都写入潜在的流中(些处为ObjectOutputStream)
8  objOutputStm.flush();
9
10  // 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,
11  // 在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器
12  objOutputStm.close();
13
14  // 调用HttpURLConnection连接对象的getInputStream()函数,
15  // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。
16  InputStream inStrm = httpConn.getInputStream(); // <===注意,实际发送请求的代码段就在这里
17
18  // 上边的httpConn.getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的输出已无意义,
19  // 既使对象输出流没有调用close()方法,下边的操作也不会向对象输出流写入任何数据.
20  // 因此,要重新发送数据时需要重新创建连接、重新设参数、重新创建流对象、重新写数据、
21  // 重新发送数据(至于是否不用重新这些操作需要再研究)
22  objOutputStm.writeObject(new String(""));
23 httpConn.getInputStream()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[/code]

总结:a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。
b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,
对connection对象的一切配置(那一堆set函数)
都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。
这些顺序实际上是由http请求的格式决定的。
如果inputStream读操作在outputStream的写操作之前,会抛出例外:
java.net.ProtocolException: Cannot write output after reading input.......

c:) http请求实际上由两部分组成,
一个是http头,所有关于此次http请求的配置都在http头里面定义,
一个是正文content。
connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,
就必须把所有的配置准备好。
d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,
实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,
而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。
至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求
正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http
请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数
之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)
都是没有意义的了,执行这些操作会导致异常的发生。


6:> Servlet端的开发注意点:

a:) 对于客户端发送的POST类型的HTTP请求,Servlet必须实现doPost方法,而不能用doGet方法。

b:) 用HttpServletRequest的getInputStream()方法取得InputStream的对象,比如:

InputStream inStream = httpRequest.getInputStream();

现在调用inStream.available()(该方法用于“返回此输入流下一个方法调用可以不受阻塞地

从此输入流读取(或跳过)的估计字节数”)时,永远都反回0。试图使用此方法的返回值分配缓冲区,

以保存此流所有数据的做法是不正确的。那么,现在的解决办法是

Servlet这一端用如下实现:

InputStream inStream = httpRequest.getInputStream();

ObjectInputStream objInStream = new ObjectInputStream(inStream);

Object obj = objInStream.readObject();

// 做后续的处理

// 。。。。。。

// 。。。 。。。

而客户端,无论是否发送实际数据都要写入一个对象(那怕这个对象不用),如:

ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm);

objOutputStrm.writeObject(new String(“”)); // 这里发送一个空数据

// 甚至可以发一个null对象,服务端取到后再做判断处理。

objOutputStrm.writeObject(null);

objOutputStrm.flush();

objOutputStrm.close();

注意:上述在创建对象输出流ObjectOutputStream时,如果将从HttpServletRequest取得的输入流

(即:new ObjectOutputStream(outStrm)中的outStrm)包装在BufferedOutputStream流里面,

则必须有objOutputStrm.flush();这一句,以便将流信息刷入缓冲输出流.如下:

ObjectOutputStream objOutputStrm = new ObjectOutputStream(new BufferedOutputStream(outStrm));

objOutputStrm.writeObject(null);

objOutputStrm.flush(); // <======此处必须要有.

objOutputStrm.close();

HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时:

System.setProperty(“sun.net.client.defaultConnectTimeout”, 超时毫秒数字符串);

System.setProperty(“sun.net.client.defaultReadTimeout”, 超时毫秒数字符串);

其中: sun.net.client.defaultConnectTimeout:连接主机的超时时间(单位:毫秒)

sun.net.client.defaultReadTimeout:从主机读取数据的超时时间(单位:毫秒)

例如:

System.setProperty(“sun.net.client.defaultConnectTimeout”, “30000”);

System.setProperty(“sun.net.client.defaultReadTime

Java中可以使用HttpURLConnection来请求WEB资源。

HttpURLConnection对象不能直接构造,需要通过URL.openConnection()来获得HttpURLConnection对象,示例代码如下:

1 String szUrl = “http://www.ee2ee.com/“;

2 URL url = new URL(szUrl);

3 HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();

HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时:

System.setProperty(“sun.net.client.defaultConnectTimeout”, 超时毫秒数字符串);

System.setProperty(“sun.net.client.defaultReadTimeout”, 超时毫秒数字符串);

其中: sun.net.client.defaultConnectTimeout:连接主机的超时时间(单位:毫秒)

sun.net.client.defaultReadTimeout:从主机读取数据的超时时间(单位:毫秒)

例如:

System.setProperty(“sun.net.client.defaultConnectTimeout”, “30000”);

System.setProperty(“sun.net.client.defaultReadTimeout”, “30000”);

JDK 1.5以前的版本,只能通过设置这两个系统属性来控制网络超时。在1.5中,还可以使用HttpURLConnection的父类URLConnection的以下两个方法:

setConnectTimeout:设置连接主机超时(单位:毫秒)

setReadTimeout:设置从主机读取数据超时(单位:毫秒)

例如:

1 HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();

2 urlCon.setConnectTimeout(30000);

3 urlCon.setReadTimeout(30000);

需要注意的是,笔者在JDK1.4.2环境下,发现在设置了defaultReadTimeout的情况下,如果发生网络超时,HttpURLConnection会自动重新提交一次请求,出现一次请求调用,请求服务器两次的问题(Trouble)。我认为这是JDK1.4.2的一个bug。在JDK1.5.0中,此问题已得到解决,不存在自动重发现象。out”, “3000

WeixinUtil.java
package com.gson.templateMessage;

/**
* Created by Administrator on 2016/8/5.
*/

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* 项目名称:wechatapi
* 类名称:WeixinUtil
* 类描述:微信基础类
* 创建人:WQ
* 创建时间:2014-1-18 下午4:05:11
* @version
*/
public class WeixinUtil {
// 日志文件
protected final static Logger log = LoggerFactory.getLogger(WeixinUtil.class);

// 接收消息类型:文本
public final static String RECRIVE_TEXT = "text";
// 接收消息类型:图片
public final static String RECRIVE_IMAGE = "image";
// 接收消息类型:语音
public final static String RECRIVE_VOICE = "voice";
// 接收消息类型:视频
public final static String RECRIVE_VIDEO = "video";
// 接收消息类型:地理位置
public final static String RECRIVE_LOCATION = "location";
// 接收消息类型:链接
public final static String RECRIVE_LINK = "link";
// 接收消息类型:推送
public final static String RECRIVE_EVENT = "event";

// 回复消息类型:文本
public final static String REQUEST_TEXT = "text";
// 回复消息类型:图片
public final static String REQUEST_IMAGE = "image";
// 回复消息类型:语音
public final static String REQUEST_VOICE = "voice";
// 回复消息类型:视频
public final static String REQUEST_VIDEO = "video";
// 回复消息类型:音乐
public final static String REQUEST_MUSIC = "music";
// 回复消息类型:图文
public final static String REQUEST_NEWS = "news";

// 事件类型:subscribe(订阅)
public final static String EVENT_SUBSCRIBE = "subscribe";
// 事件类型:unsubscribe(取消订阅)
public final static String EVENT_UNSUBSCRIBE = "unsubscribe";
// 事件类型:LOCATION(上报地理位置事件)
public final static String EVENT_LOCATION = "LOCATION";
// 事件类型:CLICK(自定义菜单点击事件)
public final static String EVENT_CLICK = "CLICK";

/**
* 扫描带参数二维码事件
* 用户扫描带场景值二维码时,可能推送以下两种事件:
1.如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
2.如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。
*/
// 事件类型:subscribe(用户未关注时,进行关注后的事件推送)
public final static String EVENT_QRCODE_SUBSCRIBE = "subscribe";
// 事件类型:scan(用户已关注时的事件推送)
public final static String EVENT_QRCODE_SCAN = "scan";

// 获取access_token的接口地址(GET) 限200(次/天)
public final static String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// 开发者可通过OpenID来获取用户基本信息 url
protected final static String GET_PERSONALINF_URL="https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
// 通过OpenID获取查询用户所在分组url
protected final static String GET_PERSONGROUPID_URL="https://api.weixin.qq.com/cgi-bin/groups/getid?access_token=ACCESS_TOKEN";
/**
*  OAuth2.0引导关注者打开 用户同意授权,获取code页面url
*  1.scope的设置为:snsapi_base(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面)
*  2.redirect_uri:授权后重定向的回调链接地址,请使用urlencode对链接进行处理  方法再commonutil的urlEncodeUTF8()
*/
public final static String FANS_GET_CODE="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
// OAuth2.0通过code换取网页授权access_token
protected final static String OAUTH2_ACCESSTOKEN_URL="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
// OAuth2.0刷新access_token
protected final static String REFRESH_ACCESSTOKEN_URL="https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
// OAuth2.0拉取用户信息(需scope为 snsapi_userinfo)
protected final static String OAUTH2_USERINFO_URL="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
// 主动发送客服消息url
protected final static String SEND_CUSTOM_URL="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
// 生成临时二维码url
protected final static String TEMPORARY_QRCODE_URL="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";
// 生成永久二维码url
protected final static String PERMANENT_QRCODE_URL="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";
// 换取二维码url
protected final static String GET_QRCODE_URL="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
// 获取关注者列表url
protected final static String GET_USERLIST_URL="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";

// 获取所有分组信息url
protected final static String GET_GROUPS_URL="https://api.weixin.qq.com/cgi-bin/groups/get?access_token=ACCESS_TOKEN";
// 创建分组url
protected final static String CREATE_GROUPS_URL="https://api.weixin.qq.com/cgi-bin/groups/create?access_token=ACCESS_TOKEN";
// 修改分组url
protected final static String UPDATE_GROUPS_URL="https://api.weixin.qq.com/cgi-bin/groups/update?access_token=ACCESS_TOKEN";
// 移动用户分组url
protected final static String REMOVE_MEMBER_URL="https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token=ACCESS_TOKEN";

// 上传多媒体文件url
protected final static String UPLOAD_MEDIA_URL="http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
// 下载多媒体文件url
protected final static String DOWNLOAD_MEDIA_URL="http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";

// 菜单创建(POST) 限100(次/天)
protected final static String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
// 菜单查询(GET)
protected final static String GET_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
// 菜单删除(GET)
protected final static String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
[/code]

CommonUtil.java
package com.gson.templateMessage;

/**
* Created by Administrator on 2016/8/5.
*/

import com.gson.bean.AccessToken;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLEncoder;

/**
*
* 项目名称:wechatsapi
* 类名称:CommonUtil
* 类描述:http请求和接收
* 创建人:WQ
* 创建时间:2014-1-26 下午7:34:54
* @version
*/
public class CommonUtil extends WeixinUtil{
/**
* 发起https请求并获取结果
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject (通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
//创建SSLContext对象,并使用我们指定的信任管理器初始化(证书过滤)
TrustManager[] tm = { new MyX509TrustManager() };
//取得SSL的SSLContext实例
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
//初始化SSLContext
sslContext.init(null, tm, new java.security.SecureRandom());
//从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn=(HttpsURLConnection) url.openConnection();
System.out.println("httpUrlConn++++++++++++++++++++"+httpUrlConn);
httpUrlConn.setSSLSocketFactory(ssf);

httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
//设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);

/*if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();*/
//当有数据需要提交时(当outputStr不为null时,向输出流写数据)
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.flush();
outputStream.close();
System.out.println("outputStream++++++++++++++"+outputStream);
}

// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
System.out.println("inputStream++++++++++++++++++"+inputStream);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.println("bufferedReader++++++++++++++++++"+bufferedReader);
/*System.out.println("bufferedReader.read()++++++++++++++++++"+bufferedReader.read());*/
/*System.out.println("bufferedReader.readLine()++++++++++++++++++"+bufferedReader.readLine());*/
String str = null;
StringBuffer buffer=new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
System.out.println("str+++++++++++++"+str);
buffer.append(str);
}
/* buffer.append(bufferedReader.read());*/

//释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
System.out.println("buffer++++++++++++++++++"+buffer.toString());
httpUrlConn.disconnect();
jsonObject=JSONObject.fromObject(buffer.toString());
System.out.println("jsonObject+++++++++++++"+jsonObject);

} catch (ConnectException ce) {
log.error("连接超时: {}",ce);
} catch (Exception e) {
log.error("https请求异常: {}", e);
}
return jsonObject;
}

/**
* 获取access_token
*
* @param appid 凭证  wx13c0a227486f7e64
* @param appsecret 密钥 864e16284d38c05c62cddc1be000351e
* @return AccessToken 返回接口凭证
*/
public static String getAccessToken(String appid, String appsecret) {
AccessToken accessToken=new AccessToken();
String requestUrl = GET_ACCESS_TOKEN_URL.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET",null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken.setAccesstoken(jsonObject.getString("access_token"));
accessToken.setExpiresin(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return accessToken.getAccesstoken().toString();
}

/**
* URL编码(utf-8)
*
* @param source
* @return String
*/
public static String urlEncodeUTF8(String source) {
String result=source;
try {
result=URLEncoder.encode(source, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}

/**
* 根据类型判断文件扩展名
*
* @param contentType 内容类型
* @return String
*/
public static String getFileExt(String contentType) {
String fileExt="";
if ("image/jpeg".equals(contentType)) {
fileExt=".jpg";
}else if ("audio/mpeg".equals(contentType)) {
fileExt=".mp3";
}else if ("audio/amr".equals(contentType)) {
fileExt=".amr";
}else if ("video/mp4".equals(contentType)) {
fileExt=".mp4";
}else if ("video/mpeg4".equals(contentType)) {
fileExt=".mp4";
}
return fileExt;
}

public static void Main() {
/*String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx13c0a227486f7e64&redirect_uri=http%3A%2F%2F122.228.158.111%2FTest%2Fservlet%2FOAuthServlet&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";*/

String url="http://122.228.158.111/Test/servlet/OAuthServlet";
System.err.println(urlEncodeUTF8(url));

// 获取接口访问凭证
/*AccessToken accessToken=getAccessToken("wx801484513be0eea4", "95441812e081c1ac6cc17dc62023f245");*/
/* if (accessToken.getAccesstoken()==null) {
System.out.println("空");
}else {
System.out.println(accessToken.getAccesstoken());
}*/
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
[/code]



版权声明:本文为博主原创文章,未经博主允许不得转载。


顶0 踩0

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: