我也对客服进行了邮箱反馈,但是只是建议我进行付费的购买,并没有说排查错误什么的!
2.
隧道协议选择Web即可
二级域名如果没有先选择不需要,如果你有自然更好。
本地端口填写一个即可,本人这里选择的80
带宽&流量选择小流量即可
购买完之后进行注册域名
4.
选择一个可用于微信开发的即可
之后再回到我的隧道里面进行绑定域名即可
构建之前,请大家大致的看微信开发平台文档一遍,比避免有些地方不懂(强烈告诫至少看一遍)
本教程只需要大家看以上四个大章即可
本教程以大家都有一个springboot的基本启动程序,为前提(能启动,controller能返回个hello,word即可)
先给出本教程需要的全部maven包 ---jdk 1.8
开发工具 idea
<!--devtools热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<!-- xml -->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<!-- fastJSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import com.alibaba.fastjson.JSON;
//引用的其他自建类包,这里就不列出了
@Slf4j
@RestController
@RequestMapping("/springsecurity/test")
public class HelloController {
@GetMapping("/weixin")
public String weixin(HttpServletRequest request, HttpServletResponse response){
return null;
}
}
先定义这样的一个类,加上一个接受微信推送消息服务器接口匹配的方法(暂时不需要定义其他类)
@GetMapping("/weixin")
public String weixin(HttpServletRequest request, HttpServletResponse response){
String echostr = null;
//token验证代码段
try{
log.info("请求已到达,开始校验token");
//这里对应的文档里面的几个参数,如果不清楚,请查看文档
if (StringUtils.isNotBlank(request.getParameter("signature"))) {
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
echostr = request.getParameter("echostr");
log.info("signature[{}], timestamp[{}], nonce[{}], echostr[{}]", signature, timestamp, nonce, echostr);
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
log.info("数据源为微信后台,将echostr[{}]返回!", echostr);
response.getOutputStream().println(echostr);
return echostr;
}
}
}catch (IOException e){
log.error("校验出错");
e.printStackTrace();
}
return echostr;
}
接受信息推送这里需要进行新加类:
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
//引用的其他自建类包,这里就不列出了
//此部分代码借鉴自网络
@Slf4j
public class ParseXml {
/**
* @author: wwy
* @description: 解析微信发来的请求(XML)
* @date 2021/1/20
* @param request
* @return java.util.Map<java.lang.String,java.lang.String>
** java.util.Map<java.lang.String,java.lang.String>
**/
public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
// 将解析结果存储在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 从request中取得输入流
InputStream inputStream = request.getInputStream();
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList) {
map.put(e.getName(), e.getText());
log.info("name:" + e.getName() + " value:"+map.get(e.getName()));
}
// 释放资源
inputStream.close();
return map;
}
}
@PostMapping("/weixin")
public void message(HttpServletRequest request, HttpServletResponse response){
try {
Map<String, String> paramMap = ParseXml.parseXml(request);
log.info(JSON.toJSONString(paramMap));
//这里把request参数传入parsexml方法进行xml到map对象的转换。
//使用map接受返回值即可
//建议大家先发给公众号消息,查看查看这玩意长什么样子!
//当然我们parseXml里面已经打印出来了
} catch (Exception e) {
e.printStackTrace();
}
}
附图供大家看!
根据官方文档可知:
基本每一个消息都会有一个MsgType来确定是什么类型的,所以我们这里要获取它:
Map<String, String> paramMap = ParseXml.parseXml(request);
String type = paramMap.get("MsgType");
看被动回复用户消息章节文档,我们最后是需要返回xml形式的给微信服务器。
所以我们的大体步骤是:
操作对象
import lombok.Data;
@Data
public class BaseMessage {
/**
* 开发者微信号
*/
private String ToUserName;
/**
* 发送方帐号(一个OpenID)
*/
private String FromUserName;
/**
* 消息创建时间 (整型)
*/
private Long CreateTime;
/**
* 消息类型(链接-link /地理位置-location /小视频-shortvideo/视频-video /语音-voice /图片-image /文本-text)
*/
private String MsgType;
/**
* 消息id,64位整型
*/
private Long MsgId;
}
@Data
public class TextMessage extends BaseMessage{
/**
* 消息内容
*/
private String Content;
//由于打印本类toString时只会打印本类有的属性,不会打印父类的,所以我们需要重写类的toString,加上本类属性和父类属性
public String toString(){
return super.toString() + "[TextMessage]:" + " Content:" + this.Content;
}
}
@Data
public class ImageMessage extends BaseMessage {
/**
* 图片链接
*/
private String PicUrl;
/**
* 图片消息媒体id,可以调用获取临时素材接口拉取数据。
*/
private String MediaId;
public String toString(){
return super.toString() + "[ImageMessage]:" + " PriUrl:" + this.PicUrl
+ " MediaId:" + this.MediaId;
}
}
@Data
public class VoiceMessage extends BaseMessage {
/**
* 语音消息媒体id,可以调用获取临时素材+接口拉取数据。
*/
private String MediaId;
/**
* 语音格式,如amr,speex等
*/
private String Format;
public String toString(){
return super.toString() + "[VoiceMessage]:" + " MediaId:" + this.MediaId
+ " Format:" + this.Format;
}
}
@Data
public class VideoMessage extends BaseMessage{
/**
* 视频消息媒体id,可以调用获取临时素材接口拉取数据。
*/
private String MediaId;
/**
* 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据
*/
private String ThumbMediaId;
public String toString(){
return super.toString() + "[VideoMessage]:" + " MediaId:" + this.MediaId
+ " ThumbMediaId:" + this.ThumbMediaId;
}
}
@Data
public class LocationMessage extends BaseMessage {
/**
* 地理位置维度
*/
private String Location_X;
/**
* 地理位置经度
*/
private String Location_Y;
/**
* 地图缩放大小
*/
private String Scale;
/**
* 地理位置信息
*/
private String Label;
public String toString(){
return super.toString() + "[LocationMessage]:" + " Location_X:" + this.Location_X
+ " Location_Y:" + this.Location_Y + " Scale:" + this.Scale
+ " Lable:" + this.Label;
}
}
@Data
public class LinkMessage extends BaseMessage{
/**
* 消息标题
*/
private String Title;
/**
* 消息描述
*/
private String Description;
/**
* 消息链接
*/
private String Url;
public String toString(){
return super.toString() + "[LinkMessage]:" + " Title:" + this.Title
+ " Description:" + this.Description + " Url:" + this.Url;
}
}
现在有了对象之间的映射但是还少一个判断是什么事件类型的枚举类,请在utils包下新建code包
在code包下新建MessageCode类
类如下(这个其实还少一两个,但是懒的加了,有需要的自己加上,此代码完全来自网上,没有多少需要修改的):
@Slf4j
public class MessageCode {
/**
* 请求消息类型:文本
*/
public static final String REQ_MESSAGE_TYPE_TEXT = "text";
/**
* 请求消息类型:图片
*/
public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
/**
* 请求消息类型:语音
*/
public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
/**
* 请求消息类型:视频
*/
public static final String REQ_MESSAGE_TYPE_VIDEO = "video";
/**
* 请求消息类型:小视频
*/
public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";
/**
* 请求消息类型:地理位置
*/
public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
/**
* 请求消息类型:链接
*/
public static final String REQ_MESSAGE_TYPE_LINK = "link";
/**
* 请求消息类型:推送
*/
public static final String REQ_MESSAGE_TYPE_EVENT = "event";
/**
* 事件类型:subscribe(订阅)
*/
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
/**
* 事件类型:unsubscribe(取消订阅)
*/
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
/**
* 事件类型:CLICK(自定义菜单点击事件)
*/
public static final String EVENT_TYPE_CLICK = "CLICK";
/**
* 事件类型:VIEW(扫描二维码事件)
*/
public static final String EVENT_TYPE_SCAN = "SCAN";
/**
* 事件类型:LOCATION(位置上报事件)
*/
public static final String EVENT_TYPE_LOCATION = "LOCATION";
/**
* 事件类型:VIEW(自定义菜单View事件)
*/
public static final String EVENT_TYPE_VIEW = "VIEW";
}
try { //try-catch后面会用到
Map<String, String> paramMap = ParseXml.parseXml(request);
String type = paramMap.get("MsgType");
//处理消息事件
if(MessageCode.REQ_MESSAGE_TYPE_TEXT.equals(type)){
log.warn("进入消息事件!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
import java.util.Date;
import java.util.Map;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;
//自建包请自导入
@Data
@Slf4j
public class MsgHandle {
/**
* 发送方账号(一个openId)
*/
private String FromUserName;
/**
* 开发者微信号
*/
private String ToUserName;
/**
* 消息创建时间
*/
private long CreateTime;
/**
* 消息类型:
* 文本:text
* 图片:image
* 语音:voice
* 视频:video
* 小视频:shortvideo
* 地理位置:location
* 链接:link
*/
private String MsgType;
/**
* 消息id,64位整数
*/
private long MsgId;
}
public String processMessage(Map<String, String> map) throws InstantiationException, IllegalAccessException{
//首先对自己的私有属性进行赋值,接着创建基类实体对象,
this.FromUserName = map.get("ToUserName"); //!!!!!这里是调换的
//特别说明这里,看上面两个图中,我们会发现关于ToUserName的说明是收到openId,所以这里是调换的!
this.ToUserName = map.get("FromUserName");
this.MsgType = map.get("MsgType");
this.CreateTime = Long.valueOf(map.get("CreateTime"));
this.MsgId = Long.valueOf(map.get("MsgId"));
BaseMessage baseMessage = null;
//目前只支持文字消息回复
//用枚举获取是什么类型,再进入里面进行具体操作
if (this.MsgType.equals(MessageCode.REQ_MESSAGE_TYPE_TEXT)) { // 文本消息
log.info("这是文本消息!");
//这里用到了MsgHelpClass的方法,请看下文的此方法代码
//参数1:this processMessage对象即可
//参数2:对应消息处理类即可
baseMessage = MsgHelpClass.setAttribute(this, TextMessage.class);
//向下转型,小心,如果报了什么class异常,就是这里的问题。
TextMessage textMessage = (TextMessage) baseMessage;
//向文字消息实体类添加私有的属性数据
textMessage.setContent("这里是测试回复");
//这里为生成xml数据的类,需要我们提供一个要生成xml数据的实体类,下文放代码
return ParseXml.textMessageToXml(textMessage);
}
if (this.MsgType.equals(MessageCode.REQ_MESSAGE_TYPE_IMAGE)) { // 图片消息
log.info("这是图片消息!");
}
if (this.MsgType.equals(MessageCode.REQ_MESSAGE_TYPE_LINK)) { // 链接消息
log.info("这是链接消息!");
}
if (this.MsgType.equals(MessageCode.REQ_MESSAGE_TYPE_LOCATION)) { // 位置消息
log.info("这是位置消息!");
}
if (this.MsgType.equals(MessageCode.REQ_MESSAGE_TYPE_VIDEO)) { // 视频/小视频消息
log.info("这是视频消息!");
}
if (this.MsgType.equals(MessageCode.REQ_MESSAGE_TYPE_VOICE)) { // 语音消息
log.info("这是语音消息!");
}
return "";
}
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
//自建类请自行导入
@Slf4j
public class MsgHelpClass {
//其实这里多加一个这个方法,而不是在processmessage里面直接进行转型,是因为会报转型错误的异常,用instanceof这里不太管用。
//方法讲解:
//规定第一个参数必须为 MsgHandle对象,用他的私有属性给实体基类进行赋值
//规定第二个参数必须为继承自BaseMessage基类的子类,用来向下转型
public static <E extends BaseMessage>E setAttribute(MsgHandle msgHandle,Class<E> eClass) throws IllegalAccessException, InstantiationException {
//newInstance 获取对象,相当于new 对象
BaseMessage baseMessage = eClass.newInstance();
baseMessage.setCreateTime(new Date().getTime());
baseMessage.setFromUserName(msgHandle.getFromUserName());
baseMessage.setMsgId(msgHandle.getMsgId());
baseMessage.setToUserName(msgHandle.getToUserName());
baseMessage.setMsgType(msgHandle.getMsgType());
log.warn("MsgHelpClass-setAttribute方法返回值如下:\n" + baseMessage.toString());
return (E) baseMessage;
}
}
public static String textMessageToXml(TextMessage textMessage) {
log.warn("ParseXml类TextMressage对象值如下:\n" + textMessage.toString());
//真正用来处理的方法,也在本类中
return XmlHandleFun(textMessage);
}
//图片处理 暂时无实现,请后续自行实现
public static String imageMessageToXml(ImageMessage imageMessage) {
log.warn("ParseXml类ImageMessage对象值如下:\n" + imageMessage.toString());
return "";
}
//音频处理 暂时无实现,请后续自行实现
public static String voiceMessageToXml(VoiceMessage voiceMessage) {
log.warn("ParseXml类VoiceMessage对象值如下:\n" + voiceMessage.toString());
return "";
}
//视频处理 暂时无实现,请后续自行实现
public static String videoMessageToXml(VideoMessage videoMessage) {
log.warn("ParseXml类VideoMessage对象值如下:\n" + videoMessage.toString());
return "";
}
//其余无写的,请自行添加
//本类讲解,参数必须是一个继承自baseMessage基类的子类对象
//返回值为String,生成的xml数据我们需要的string类型的,返回给服务器的也是String类型的
//本文需要一定的dom4j知识,推荐大家去https://www.cnblogs.com/qqran/p/12520901.html这里进行速成,很快几分钟
//当然不想看的话,后面也有简单的介绍
private static <T extends BaseMessage> String XmlHandleFun(T object){
//Document对象,后续用他生成xml结构,并调用他的方法进行string类型数据返回
Document dou = null;
//用来判断下文的if是否还继续判断,当然这里这个判断是重复的,大家可以在看懂此代码块之后,自己决定是否删除
boolean isif = true;
try {
//开始创建dom结构
dou = DocumentHelper.createDocument();
//dou.addElement 创建唯一的全局父节点,根据官方文档的格式,返回的xml'格式基本只有最多3级
Element root = dou.addElement("xml");
//root.addElement 在root节点下,创建一个节点,相当于二级节点<ToUserName></ToUserName>
//attText 为添加二级节点的内容,<ToUserName>内容</ToUserName>
//补充知识:如果要给此行添加xml属性,使用如下代码-> root.addAttribute("id", "属性");
//值为<xml id="属性"></xml>
//获取对象的值,进行字符串拼接
Element emp = root.addElement("ToUserName").addText("<![CDATA[" + object.getToUserName() + "]]>");
Element emp1 = root.addElement("FromUserName").addText("<![CDATA[" + object.getFromUserName() + "]]>");
Element emp2 = root.addElement("CreateTime").addText(String.valueOf(object.getCreateTime()));
Element emp3 = root.addElement("MsgType").addText("<![CDATA[" + object.getMsgType() + "]]>");
//判断传入的对象是否是它的实例
//是的话进行转型,并添加属于自己类的特有的属性!
if(object instanceof TextMessage && isif){
TextMessage textMessage = (TextMessage) object;
Element emp4 = root.addElement("Content").addText("<![CDATA[" + textMessage.getContent() + "]]>");
isif = false;
}
if(object instanceof ImageMessage && isif){
ImageMessage imageMessage = (ImageMessage) object;
Element emp4 = root.addElement("Image");
emp4.addElement("MediaId").addText("<![CDATA[" + imageMessage.getMediaId() + "]]>");
isif = false;
}
if(object instanceof VoiceMessage && isif){
VoiceMessage voiceMessage = (VoiceMessage) object;
Element emp4 = root.addElement("Voice");
emp4.addElement("MediaId").addText("<![CDATA[" + voiceMessage.getMediaId() + "]]>");
isif = false;
}
if(object instanceof VideoMessage && isif) {
VideoMessage videoMessage = (VideoMessage) object;
Element emp4 = root.addElement("Video");
emp4.addElement("MediaId").addText("<![CDATA[" + videoMessage.getMediaId() + "]]>");
emp4.addElement("Title").addText("<![CDATA[" + videoMessage.getTitle() + "]]>");
emp4.addElement("Description").addText("<![CDATA[" + videoMessage.getDescription() + "]]>");
isif = false;
}
}catch(Exception e){
log.error("出现错误!XmlHandleFun");
e.printStackTrace();
}
//生成的xml是附带<?xml version="1.0" encoding="UTF-8"?>此行的,我还并没有测试带上返回给微信服务器是否可行,当前没被注释的是去除此行的,如果使用注释的一行则是直接返回生成的,带上此头部的
int count = "encoding=\"UTF-8\"?".length();
String result = dou.asXML();
result = result.substring(result.indexOf("encoding=\"UTF-8\"?") + count + 1);
return result.trim();
// return dou.asXML();
}
以上配置完成之后我们就可以进行HelloController剩下的部分了
//我们只需要在原有的判断条件下增加如下的代码:
if(MessageCode.REQ_MESSAGE_TYPE_TEXT.equals(type)){
MsgHandle msgHandle = new MsgHandle();
ResultRes.response(msgHandle.processMessage(paramMap),response);
}
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringEscapeUtils;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.thymeleaf.util.StringUtils;
@Slf4j
public class reresult {
public static void response(String data, HttpServletResponse response) {
//用此方法进行xml文件的转义和format效果类似,因为上文的代码中,返回的string数据里面的,< >符合已经被转义无法正常传输给微信服务器识别
data = StringEscapeUtils.unescapeXml(data);
log.info(data);
//如果数据为空,直接返回
if(StringUtils.isEmpty(data)){
log.error("数据为空!");
return;
}
try {
//进行编码规定,返回数据!
response.setCharacterEncoding("UTF-8");
PrintWriter printWriter = response.getWriter();
printWriter.print(data);
printWriter.close();
}catch (IOException io){
log.error(io.getMessage());
io.printStackTrace();
}
}
/**
* @Title: format
* @Description: 格式化输出xml字符串
* @param str
* @return String
* @throws Exception
* 这里的代码是网上的,本来要用的,但是也最后没用,是用来解决xml里面的<>符合传输的时候被转义的问题
*/
public static String format(String str) throws Exception {
SAXReader reader = new SAXReader();
// 创建一个串的字符输入流
StringReader in = new StringReader(str);
Document doc = reader.read(in);
// 创建输出格式
OutputFormat formater = OutputFormat.createPrettyPrint();
// 设置xml的输出编码
formater.setEncoding("utf-8");
// 创建输出(目标)
StringWriter out = new StringWriter();
// 创建输出流
XMLWriter writer = new XMLWriter(out, formater);
// 输出格式化的串到目标中,执行后。格式化后的串保存在out中。
writer.write(doc);
writer.close();
// 返回格式化后的结果
return out.toString();
}
}
到这里正常情况下,已经可以对用户输入的普通文本消息进行自动回复了!
String type = paramMap.get("MsgType");下
加入 String event = null;
//获取自定义点击/推送事件
if(paramMap.get("Event") != null){
event = paramMap.get("Event");
}
//订阅消息事件
if(MessageCode.EVENT_TYPE_SUBSCRIBE.equals(event)){
String token = GetBodyMessage.getAcces_Token("wx59fa3e56c3448f46");
String body = GetBodyMessage.getBodyJson();
String s = httpsRequest.httpsRequests("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token, "POST", body);
System.err.println(s);
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class GetBodyMessage {
//添加菜单自定义json数据
public static String getBodyJson(){
Map<String, Object> mapbutton = new HashMap<>();
Map<String, Object> mapbody = new HashMap<>();
Map [] strargs = new Map[1];
mapbody.put("type","view");
mapbody.put("name","成绩查询!");
mapbody.put("key","message");
mapbody.put("url","http://www.baidu.com");
strargs[0] = mapbody;
mapbutton.put("button", strargs);
String body = JSON.toJSONString(mapbutton);
log.error(body);
//自定义菜单官网返回数据为json数据!
return body;
}
//获取access_token
public static String getAcces_Token(String appid){
String token = "grant_type=client_credential&appid=" + appid +"&secret=xxxxxxxxxxxxxxxxxxxxxx";
//httpRequest代码在下文
String result = httpRequest.httpRequests("https://api.weixin.qq.com/cgi-bin/token","GET",token);
Map map = JSONArray.parseObject(result);
System.out.println(map.get("access_token"));
return (String) map.get("access_token");
}
}
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class httpRequest {
//处理http请求 requestUrl为请求地址 requestMethod请求方式,值为"GET"或"POST"
public static String httpRequests(String requestUrl,String requestMethod,String outputStr){
StringBuffer buffer=null;
try{
URL url=new URL(requestUrl);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod(requestMethod);
conn.connect();
//往服务器端写内容 也就是发起http请求需要带的参数
if(null!=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
//读取服务器端返回的内容
InputStream is=conn.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
buffer=new StringBuffer();
String line=null;
while((line=br.readLine())!=null){
buffer.append(line);
}
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
}
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
public class httpsRequest {
/*
* 处理https GET/POST请求
* 请求地址、请求方法、参数
*
*/
public static String httpsRequests(String requestUrl,String requestMethod,String outputStr){
StringBuffer buffer=null;
try{
//创建SSLContext
SSLContext sslContext=SSLContext.getInstance("SSL");
TrustManager[] tm={new MyX509TrustManager()};
//初始化
sslContext.init(null, tm, new java.security.SecureRandom());;
//获取SSLSocketFactory对象
SSLSocketFactory ssf=sslContext.getSocketFactory();
URL url=new URL(requestUrl);
HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod(requestMethod);
//设置当前实例使用的SSLSoctetFactory
conn.setSSLSocketFactory(ssf);
conn.connect();
//往服务器端写内容
if(null!=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
//读取服务器端返回的内容
InputStream is=conn.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
buffer=new StringBuffer();
String line=null;
while((line=br.readLine())!=null){
buffer.append(line);
}
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
}
https请求如果报错,可能还需要导入服务端的安全证书步骤如下:
//用户点击自定义菜单事件
if(MessageCode.EVENT_TYPE_CLICK.equals(event)){
//事件KEY值,与自定义菜单接口中KEY值对应
String eventKey = "message";
log.warn(JSON.toJSONString(paramMap));
if(eventKey.equals(paramMap.get("EventKey"))){
log.warn("进入成绩查询点击事件,开始处理并返回!");
}
}
//用户点击自定义链接事件
if(MessageCode.EVENT_TYPE_VIEW.equals(event)){
log.warn("进入百度页面跳转事件!");
}
内容来源于网络,如有侵权,请联系作者删除!