如果没有素材管理功能的话,公众号配置了服务信息,自动回复消息也只能动态的创建文本消息,图片,语音,视频,图文消息都要结合素材管理接口,得到素材的MediaId和图片的url来进行动态的自定义消息回复。
素材pojo
public class WeixinResource {
private static final long serialVersionUID = 1L;
private Integer id;
private String resourceName; // 资源名称
private String resourceType; // 资源类型
private String resourceLength; // 资源类型
private String resourceContentType; // MIME类型
private String resourceMediaId; // 资源mediaid
private String resourceUrl; // 资源链接
private Date createdTime; // 创建时间
private Date updatedTime; // 更新时间
private String createUser; // 创建人
private String updateUser; // 更新人
private String resourcePath; // resource_path
}
素材上传页面
一个简单的新增素材的页面。
素材新增代码
校验规则
public String addEntity(HttpServletRequest request, @RequestParam(value = "file", required = false) MultipartFile resourceFile, HttpServletResponse response) throws Exception {
String resourceName = this.getParameter(request, "resourceName");
String resourceType = this.getParameter(request, "resourceType");
WeixinResource wr = new WeixinResource();
wr.setResourceName(resourceName);
wr.setResourceType(resourceType);
String filename = resourceFile.getOriginalFilename();
if (StringUtils.isNotEmpty(filename)) {
String fileName = WeixinUtil.getFileName(filename);
String fileType = WeixinUtil.getFileType(filename);
SimpleDateFormat sdf = new SimpleDateFormat(getTimeFormat());
fileName = fileName + "_" + sdf.format(new Date()) + fileType;
logger.info("资源文件名称:" + fileName);
String uploadPath = loader.getProperty("upload.path");
//获取文件上传的实际路径
uploadPath = request.getSession().getServletContext().getRealPath(uploadPath);
File targetFile = new File(uploadPath + "/" + fileName);
File targetDir = new File(uploadPath + "/");
if (!targetDir.exists()) {
logger.info("文件上传路径不存在,创建路径:" + uploadPath);
targetDir.mkdirs();
}
int fileSize = (int) resourceFile.getSize();
//对各素材大小进行控制,校验规则
// 此处省略文件大小
wr.setResourceLength(String.valueOf(fileSize));
resourceFile.transferTo(targetFile);
wr.setResourcePath(fileName);
//默认全部调用接口
String fileTypeNew = "";
boolean isWrongType = false;
//需要调用接口 并对文件类型进行控制
// 此处省略文件类型的校验
if (isWrongType) {
return "error";
}
wr.setResourceContentType(fileTypeNew);
String appId=loader.getProperty("appId");
String appSecret=loader.getProperty("appSecret");
String key=loader.getProperty("tokenKey");
// 调用接口获取access_token
AccessToken at = CommonUtil.getToken(appId, appSecret);
String accesstoken=at.getAccessToken();
String url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token="+accesstoken+"&type="+fileTypeNew;
String result = UploadUtil.send(url,targetFile.getPath());
JSONObject jsonObj = JSONObject.fromObject(result);
logger.info("上传永久素材返回报文:"+jsonObj);
try {
if(jsonObj.containsKey("errcode")){
String errmsg=jsonObj.getString("errmsg");
logger.info("媒体上传微信服务器失败"+errmsg);
return "error";
}else{
String mediaId = jsonObj.getString("media_id");
wr.setResourceMediaId(mediaId);
}
} catch (Exception e) {
return "error";
}
}
else{
return "error";
}
weixinResourceService.save(wr);
return "success";
}
````
//模拟form表单的形式 ,上传文件 以输出流的形式把文件写入到url中,然后用输入流来获取url的响应
public static String send(String url, String filePath) throws IOException {
String result = null;
File file = new File(filePath);
if (!file.exists() || !file.isFile()) {
throw new IOException("文件不存在");
}
/**
* 第一部分
*/
URL urlObj = new URL(url);
// 连接
HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
/**
* 设置关键值
*/
con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false); // post方式不能使用缓存
// 设置请求头信息
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
// 设置边界
String BOUNDARY = "----------" + System.currentTimeMillis();
con.setRequestProperty("Content-Type", "multipart/form-data; boundary="
+ BOUNDARY);
// 请求正文信息
// 第一部分:
StringBuilder sb = new StringBuilder();
sb.append("--"); // 必须多两道线
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data;name=\"media\";filename=\""
+ file.getName() + "\";filelength=\""+file.length()+"\"\r\n");
String contentType = new MimetypesFileTypeMap()
.getContentType(file);
String filename = file.getName();
sb.append("Content-Type:application/octet-stream\r\n\r\n");
byte[] head = sb.toString().getBytes("utf-8");
// 获得输出流
OutputStream out = new DataOutputStream(con.getOutputStream());
// 输出表头
out.write(head);
// 文件正文部分
// 把文件已流文件的方式 推入到url中
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
in.close();
// 结尾部分
byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
out.write(foot);
if(filename.endsWith(".mp4")){
// 视频类文件多传一个form表单
out.write(("--" + BOUNDARY + "\r\n").getBytes());
out.write("Content-Disposition: form-data; name=\"description\";\r\n\r\n".getBytes());
out.write(String.format("{\"title\":\"%s\", \"introduction\":\"%s\"}","app录取","这个一个测试视频").getBytes());
out.write(("\r\n--" + BOUNDARY + "--\r\n\r\n").getBytes());
}
out.flush();
out.close();
StringBuffer buffer = new StringBuffer();
BufferedReader reader = null;
try {
// 定义BufferedReader输入流来读取URL的响应
reader = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
if (result == null) {
result = buffer.toString();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
}
return result;
}
然后,自定义消息回复就会更加多样灵活了。