Java后台微信内容安全接口imgSecCheck,msgSecCheck

微信内容安全接口imgSecCheck,msgSecCheck

  • 1.文件上传
  • 2.返回结果实体类
  • 3.任务处理
  • 4.检测工具类
  • 5.Controller

官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/sec-check/security.msgSecCheck.html
参考文档:https://blog.csdn.net/u010651369/article/details/101697940?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

常见问题:{"errcode":41005,"errmsg":"media data missing hint:"}

1.文件上传

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class UploadAction {
    /**
	 * 上传二进制文件
	 * @param graphurl 接口地址
	 * @param file 图片文件
	 * @return
	 */
	public static String uploadFile(String graphurl, MultipartFile file) {
		String line = null;// 接口返回的结果
		try {
			// 换行符
			final String newLine = "\r\n";
			final String boundaryPrefix = "--";
			// 定义数据分隔线
			String BOUNDARY = "========7d4a6d158c9";
			// 服务器的域名
			URL url = new URL(graphurl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			// 设置为POST情
			conn.setRequestMethod("POST");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求头参数
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("Charsert", "UTF-8");
			conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1");
			OutputStream out = new DataOutputStream(conn.getOutputStream());

			// 上传文件
			StringBuilder sb = new StringBuilder();
			sb.append(boundaryPrefix);
			sb.append(BOUNDARY);
			sb.append(newLine);
			// 文件参数,photo参数名可以随意修改
			sb.append("Content-Disposition: form-data;name=\"image\";filename=\"" + "https://api.weixin.qq.com" + "\"" + newLine);
			sb.append("Content-Type:application/octet-stream;charset=UTF-8");
			// 参数头设置完以后需要两个换行,然后才是参数内容
			sb.append(newLine);
			sb.append(newLine);

			// 将参数头的数据写入到输出流中
			out.write(sb.toString().getBytes());

			// 读取文件数据
			out.write(file.getBytes());
			// 最后添加换行
			out.write(newLine.getBytes());

			// 定义最后数据分隔线,即--加上BOUNDARY再加上--。
			byte[] end_data = (newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine).getBytes();
			// 写上结尾标识
			out.write(end_data);
			out.flush();
			out.close();
			// 定义BufferedReader输入流来读取URL的响应
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			while ((line = reader.readLine()) != null) {
				return line;
			}
		} catch (Exception e) {
			System.out.println("发送POST请求出现异常!" + e);
		}
		return line;
	}
}

2.返回结果实体类

import java.io.Serializable;

public class AccessTokenWX implements Serializable {
	
	private static final long serialVersionUID = 2336546555320388951L;

	private String errCode;
	private String errMsg;

	public String getErrCode() {
		return errCode;
	}

	public void setErrCode(String errCode) {
		this.errCode = errCode;
	}

	public String getErrMsg() {
		return errMsg;
	}

	public void setErrMsg(String errMsg) {
		this.errMsg = errMsg;
	}

	@Override
	public String toString() {
		return "{" +
				"errCode='" + errCode + '\'' +
				", errMsg='" + errMsg + '\'' +
				'}';
	}
}

3.任务处理

import com.alibaba.fastjson.JSON;
import com.tj.common.web.controller.AccessTokenWX;
import com.tj.common.web.controller.UploadAction;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.RecursiveTask;

public class CheckTask extends RecursiveTask<AccessTokenWX> {
    private String url;
    private MultipartFile file;
    private String content;
    public CheckTask(){}

    public CheckTask(String url, MultipartFile file, String content) {
        this.url = url;
        this.file = file;
        this.content = content;
    }

    @Override
    protected AccessTokenWX compute() {
        AccessTokenWX result = new AccessTokenWX();
        try {
            if (null == content){
                String json = UploadAction.uploadFile(url, file);
                result = JSON.parseObject(json, AccessTokenWX.class);
            }else {
                RestTemplate rest = new RestTemplate();
                Map<String,Object> param = new HashMap<String,Object>();
                param.put("content", content);
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                HttpEntity requestEntity = new HttpEntity(param, headers);
                ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
                String json = new String(entity.getBody(),"utf-8");
                result = JSON.parseObject(json, AccessTokenWX.class);
            }
        } catch (Exception e) {
            result.setErrCode("500");
            result.setErrMsg("system错误");
        }
        return result;
    }
}

4.检测工具类

import com.tj.common.web.controller.AccessTokenWX;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;

/**
 * 微信检测违规图片或文字接口
 * 2020-04-02 by Jack魏
 */
public class WeiXinViolationCheckUtil {
    /**
     * 微信图片检测接口
     */
    static String IMG_CHECK = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=";
    /**
     * 微信文字检测接口
     */
    static String TXT_CHECK = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=";

    static private Logger logger = LoggerFactory.getLogger(WeiXinViolationCheckUtil.class);

    /**
     * file:图片路径地址
     * content:文字内容
     * token:微信token
     */
    public static Map checkImgOrMsg(MultipartFile file, String content, String token) throws ExecutionException, InterruptedException {
        Map<String, Object> resultMap = new HashMap<>();
        ForkJoinPool pool = new ForkJoinPool();
        String contentUrl = TXT_CHECK + token;
        String imgUrl = IMG_CHECK + token;
        // 返回为0说明检测正常
        String ok = "0";
        ForkJoinTask<AccessTokenWX> contentResult = null;
        ForkJoinTask<AccessTokenWX> imgResult = null;
        resultMap.put("all", "ok");

        if (null != content && content.trim().length()>0){
            CheckTask contentTask = new CheckTask(contentUrl, null, content);
            contentResult = pool.submit(contentTask).fork();
            logger.info("文字检测结果==="+contentResult.get());
        }
        if(null!=file && !file.isEmpty()){
            CheckTask contentTask = new CheckTask(imgUrl, file, null);
            imgResult = pool.submit(contentTask).fork();
            logger.info("图片检测结果==="+imgResult.get());
        }
        if (null != contentResult){
            resultMap.put("content", contentResult.get().getErrCode());
            if (!ok.equals(contentResult.get().getErrCode())){
                resultMap.put("all", "err");
            }
        }
        if (null != imgResult){
            resultMap.put("img", imgResult.get().getErrCode());
            if (!ok.equals(imgResult.get().getErrCode())){
                resultMap.put("all", "err");
            }
        }
        return resultMap;
    }
}

5.Controller

import com.tj.common.util.check.WeiXinViolationCheckUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;
import java.util.concurrent.ExecutionException;

@Controller
@RequestMapping("/sec")
@Api(tags = "文章图片检测是否违规")
public class SecurityCheckController {
    String APPID = "XXX";
    String SECRET = "XXX";
    String GET_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+SECRET;
    static Long oldTime = 0L;
    static String tokenCache = "";
    // 过期时间,2h-1m
    static Long outTime = 7200000L - 60000;

    public @ResponseBody String getToken(){
        Long nowTime = System.currentTimeMillis();
        Long cacheTime = nowTime - oldTime;
        if (oldTime <=0 || cacheTime > outTime){
            RestTemplate restTemplate;
            restTemplate = new RestTemplate();
            String json = restTemplate.getForObject(GET_TOKEN, String.class);
            tokenCache = json.split("\"access_token\":\"")[1].split("\",\"")[0].trim();
            oldTime = System.currentTimeMillis();
            return tokenCache;
        }else {
            return tokenCache;
        }
    }

    @ApiOperation("检测文字或者图片是否存在违规")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "content", value = "文字"),
            @ApiImplicitParam(name = "file", value = "图片上传路径")
    })
    @RequestMapping(value = "/checkImgOrMsg", method = RequestMethod.POST)
    public @ResponseBody Map check(@RequestParam(value = "file", required = false) MultipartFile file,
                                   @RequestParam(value = "content", required = false) String content) throws ExecutionException, InterruptedException {
        String token = getToken();
        return WeiXinViolationCheckUtil.checkImgOrMsg(file, content, token);
    }
}

你可能感兴趣的:(常见问题)