三方接口调用-【1】配置

1、讯飞性别年龄识别

package com.day.controller;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
/**
 * 1.年龄识别
 * 2.如果是一个restful接口(json格式),一般将Content-Type设置为application/json; charset=UTF-8
 * 3.如果是文件上传,  一般Content-Type设置为multipart/form-data
 * 4.如果普通表单提交,一般Content-Type设置为application/x-www-form-urlencoded; charset=UTF-8
 */
public class HelloPost {
    public static String url="http://tupapi.xfyun.cn/v1/age";
    public static String APPID = "";
    public static String APIKey = "";
    public static String IMAGE_NAME="src/main/resources/static/1.jpg";
    public static String IMAGE_PATH="src/main/resources/static/1.jpg";
    public static String XCurTime=System.currentTimeMillis() / 1000L + "";
    public static String myParam = "{\"image_name\":\"" + IMAGE_NAME + "\"}";
    public static String checkSum;
    static {
        try {
            checkSum = DigestUtils.md5Hex(APIKey + XCurTime
                    + new String(Base64.encodeBase64(myParam.getBytes("UTF-8"))));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    /**主函数*/
    public static void main(String args[]){
        String result=sendPost(url,"&key=1&secret=2");
        System.out.println("调用结果 ==》"+result);
    }
    public static String sendPost(String url, String params) {
        PrintWriter printWriter = null;
        BufferedReader bufferedReader = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection myURLConnection = realUrl.openConnection();
 
            //设置通用的请求属性(Header里的参数)
            myURLConnection.setRequestProperty("accept", "*/*");
            myURLConnection.setRequestProperty("connection", "Keep-Alive");
            myURLConnection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            /**1.浏览器的原生form表单,一般用于表单提交
             * 2.在 Http Request Header 中配置以下参数*/
            myURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
            myURLConnection.setRequestProperty("X-Appid",APPID);
            myURLConnection.setRequestProperty("X-CurTime",XCurTime);
            myURLConnection.setRequestProperty("X-Param",new String(Base64.encodeBase64(myParam.getBytes("UTF-8"))));
            myURLConnection.setRequestProperty("X-CheckSum",checkSum);
            // 发送POST请求必须设置如下两行
            myURLConnection.setDoOutput(true);
            myURLConnection.setDoInput(true);
            /**1.printWriter:我们一般用来传的是对像
             * 2.而outputStream用来传的是二进制,故上传文件时,一定要使用此。
             * 3.将图片的二进制数据写入 Http Request Body 中*/
 
            //获取URLConnection对象对应的输出流   发送图片数据
            OutputStream outputStream = myURLConnection.getOutputStream();
            byte[] imageByteArray=read(IMAGE_PATH);
            outputStream.write(imageByteArray);
 
            // 获取URLConnection对象对应的输出流  发送参数对象
            printWriter = new PrintWriter(outputStream);
            // 发送请求参数
            printWriter.print(params);
            // flush输出流的缓冲
            printWriter.flush();
            printWriter.close();
            outputStream.flush();
            outputStream.close();
 
 
            // 定义BufferedReader输入流来读取URL的响应
            bufferedReader = new BufferedReader(
                    new InputStreamReader(myURLConnection.getInputStream()));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                result += line;
            }
        }catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }finally{//使用finally块来关闭输出流、输入流
            try{
                if(printWriter!=null){
                    printWriter.close();
                }
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return result;
    }
    /**读取图片或音频文件*/
    public static byte[] read(String filePath) throws IOException {
        InputStream inputStream = new FileInputStream(filePath);
        byte[] data = inputStream2ByteArray(inputStream);
        inputStream.close();
        return data;
    }
    private static byte[] inputStream2ByteArray(InputStream inputStream) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024 * 4];
        int n = 0;
        while ((n = inputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, n);
        }
        return byteArrayOutputStream.toByteArray();
    }
    /**判断文件是否是以二进制流存储的*/
    public static boolean isBinary(File file) {
        boolean isBinaryFlag = false;
        FileInputStream fileInputStream=null;
        try {
            fileInputStream = new FileInputStream(file);
            long len = file.length();
            for (int j = 0; j < (int) len; j++) {
                int t = fileInputStream.read();
                if (t < 32 && t != 9 && t != 10 && t != 13) {
                    isBinaryFlag = true;
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try{
                fileInputStream.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return isBinaryFlag;
    }
}

2、讯飞离线语音合成Windows/Linux

# 1、离线语音合成调用主函数(离线语音合成调用属于简单的,无回调函数)
package com.iflytek;
import com.iflytek.util.Step2_tts_thread;
import com.iflytek.util.Step3_audioFormat;
import java.util.Scanner;
import javax.sound.sampled.*;
 
/**
 * 请注意!!!
 * 1.首选到控制台https://console.xfyun.cn/services/aisound下载普通离线语音合成的Windows MSC。
 * 2.普通离线语音合成Windows MSC解压后,把bin目录下msc文件夹与dll文件拷贝到res目录下。
 * 3.最后请替换Step2_tts_thread中的appid值,appid值在下载页面控制台可以看到。
 */
 
public class OfflineTtsMain {
	//录音相关参数
	public static AudioFormat audioFormat;
	public static SourceDataLine sourceDataLine;
	public static void main(String[] args) throws Exception {
		System.out.println("输入y开始体验普通离线语音合成...");
		Scanner myScanner = new Scanner(System.in);
		String userCommand = myScanner.next();
		long startTime = System.currentTimeMillis();
		if(userCommand.equals("y")){
			audioFormat = Step3_audioFormat.getAudioFormat(audioFormat);//构造具有线性 PCM 编码和给定参数的 AudioFormat。
			DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,audioFormat, AudioSystem.NOT_SPECIFIED);
			sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
			Step2_tts_thread myThread=new Step2_tts_thread();
			myThread.start();
		}
	}
}

# 2、根据MSC文档用JAVA重写方法
package com.iflytek.service;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
 
public interface Step1_tts_dll extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  byte[]/Pointer,回调函数里此类型需用String来对应。
     * 4.int      对应  int
     * 5.无参     对应  void
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback,离线语音合成无回调
     */
    //加载dll动态库并实例化,从而使用其内部的方法
    Step1_tts_dll INSTANCE = (Step1_tts_dll) Native.loadLibrary("res/msc_x64.dll", Step1_tts_dll.class);
 
    //定义登录方法
    public int MSPLogin(String usr, String pwd, String params);
 
    //开始一次普通离线语音合成
    public String QTTSSessionBegin(String params, IntByReference errorCode);
 
    //写入需要合成的文本
    public int QTTSTextPut(String sessionID,String textString,int textLen,String params);
 
    //获取离线合成的音频
    public Pointer QTTSAudioGet(String sessionID, IntByReference audioLen, IntByReference synthStatus, IntByReference errorCode);
 
    //结束本次普通离线语音合成
    public int QTTSSessionEnd(String sessionID, String hints);
 
    //定义退出方法
    public int MSPLogout();
}

# 3、把调用步骤依次写进线程类 
package com.iflytek.util;
import com.iflytek.OfflineTtsMain;
import com.iflytek.service.Step1_tts_dll;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
 
import java.io.ByteArrayOutputStream;
import java.util.Scanner;
 
public class Step2_tts_thread extends Thread{
	public static int total_audio_length=0;
	public static ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
	public void run() {
		while (true) {
			//登录参数
			String login_params = "appid = 替换你的appid, work_dir = ./res";
			//第一个参数为用户名,第二个参数为密码,传null即可
			int ret = Step1_tts_dll.INSTANCE.MSPLogin(null, null, login_params);
			if (ret != 0) {//登录成功标志ret为0
				System.out.println("登录失败...请检查");
				System.exit(1);
			} else {
				//System.out.println("登录成功...");
			}
			//请让一让,A02-02-03
			//开始一次普通离线语音合成会话
			String session_begin_params = "engine_type = local, voice_name = xiaoyan, text_encoding = UTF8, tts_res_path = fo|res/tts/xiaoyan.jet;fo|res/tts/common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";
			IntByReference errorCode = new IntByReference(-100);
			String session_id = Step1_tts_dll.INSTANCE.QTTSSessionBegin(session_begin_params,errorCode);
			if(errorCode.getValue()==0){
				//System.out.println("开启普通离线语音合成成功,session_id是:"+session_id);
			}else{
				System.out.println("开启普通离线语音合成失败:"+errorCode.getValue());
			}
 
			//写入需要合成的文本
			System.out.println("\033[43;34;4m"+"请输入你要合成的文本并回车"+"\033[0m");
			Scanner myScanner = new Scanner(System.in);
			String tts_text =myScanner.nextLine();
			//System.out.println(tts_text);//注意获取的文本是否完整
			ret= Step1_tts_dll.INSTANCE.QTTSTextPut(session_id, tts_text, tts_text.getBytes().length,null);
			if(ret==0){
				//System.out.println("写入合成文本成功...");
			}else{
				System.out.println("写入合成文本失败:"+ret);
			}
 
			//循环获取离线合成的音频,并实时进行播放
			IntByReference audio_len=new IntByReference(-100);
			IntByReference synth_status=new IntByReference(-100);
			errorCode=new IntByReference(-100);
			try{
				//实时播放
				OfflineTtsMain.sourceDataLine.open(OfflineTtsMain.audioFormat);
				OfflineTtsMain.sourceDataLine.start();
			}catch (Exception e){
				e.printStackTrace();
			}
			//int i=0;
			while (true) {
				Pointer audioPointer = Step1_tts_dll.INSTANCE.QTTSAudioGet(session_id,audio_len,synth_status,errorCode);
				byte[] audioDataByteArray=null;
				if(audioPointer!=null){
					audioDataByteArray=audioPointer.getByteArray(0,audio_len.getValue());
				}
				if (errorCode.getValue()==0){
					//System.out.println("正常获取音频中...");
				}else{
					System.out.println("获取音频发生错误:"+errorCode);
					break;
				}
				if (audioDataByteArray!=null ){
					try{
						//实时播放
						OfflineTtsMain.sourceDataLine.write(audioDataByteArray, 0, audio_len.getValue());
						/*i=i+1;//实现暂停的效果
						System.out.println(i);
						if(i==5){
							OfflineTtsMain.sourceDataLine.stop();
							Thread.sleep(5000);
						}
						if(i==6){
							OfflineTtsMain.sourceDataLine.start();
						}*/
						//将数据写入字节数组的输出流,用来生成音频文件
						byteArrayOutputStream.write(audioDataByteArray, 0, audio_len.getValue());
					}catch(Exception e){
						e.printStackTrace();
					}
					//计算总音频长度,用来生成音频文件
					total_audio_length=total_audio_length+audio_len.getValue();
				}
				if (synth_status.getValue()==2){
					//说明音频已经取完,退出本次循环
					try{
						OfflineTtsMain.sourceDataLine.drain();
						OfflineTtsMain.sourceDataLine.close();
						byteArrayOutputStream.flush();
						byteArrayOutputStream.close();
					}catch (Exception e){
						e.printStackTrace();
					}
					break;
				}
			}
 
			//把合成的音频存放为wav格式
			String dateAsFileName= String.valueOf(System.currentTimeMillis());//用当前时间标记文件名
			Boolean waveProductFlag=Step4_wave_product.waveProduct(total_audio_length,byteArrayOutputStream,"./res/"+dateAsFileName+".wav");
			if(waveProductFlag){
				System.out.println("生成音频文件成功:"+dateAsFileName+".wav");
			}else{
				System.out.println("生成音频文件失败...");
			}
 
			//结束本次普通离线语音合成
			ret=Step1_tts_dll.INSTANCE.QTTSSessionEnd(session_id, "正常退出");
			if(ret==0){
				//System.out.println("离线语音合成正常退出...");
			}else{
				System.out.println("离线语音合成退出异常:"+ret);
			}
 
			//执行最终退出
			ret = Step1_tts_dll.INSTANCE.MSPLogout();
			if (ret == 0) {
				//System.out.println("正常退出...");
			} else {
				System.out.println("异常退出:"+ret);
			}
 
			//是否退出Java程序
			System.out.println("\33[43;31;4m"+"结束合成:输入n,继续合成:输入其他内容"+"\33[0m");
			Scanner myScanner2 = new Scanner(System.in);
			String userCommand = myScanner2.nextLine();
			if(userCommand.equals("n")){
				OfflineTtsMain.sourceDataLine.stop();
				OfflineTtsMain.sourceDataLine.close();
				System.exit(0);
			}
		}
	}
}

# 4、生成16K、16BIT单声道音频流
package com.iflytek.util;
import javax.sound.sampled.AudioFormat;
 
public class Step3_audioFormat {
    //构造线程参数
    //16k采样率的16bit音频,一帧的大小为640B, 时长20ms
    /**
     sampleRate - 每秒样品数
     sampleSizeInBits - 每个样本中的位数
     channels - 通道数(1为mono,2为立体声等)
     signed - 表示数据是签名还是无符号
     bigEndian - 指示单个样本的数据是否以大字节顺序存储( false表示小端)
     */
    public static AudioFormat getAudioFormat(AudioFormat audioFormat) {
        audioFormat=new AudioFormat(16000F, 16, 1,true,false);
        // true,false 指示是以 big-endian 顺序还是以 little-endian 顺序存储音频数据。
        return audioFormat;//构造具有线性 PCM 编码和给定参数的 AudioFormat。
    }
}

# 5、生成WAV音频所需的文件头
package com.iflytek.util;
 
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
 
public class Step4_wave_product {
    public static byte[] RIFF = "RIFF".getBytes();
    public static byte[] RIFF_SIZE = new byte[8];
    public static byte[] RIFF_TYPE = "WAVE".getBytes();
    public static byte[] FORMAT = "fmt ".getBytes();
    public static byte[] FORMAT_SIZE = new byte[4];
    public static byte[] FORMAT_TAG = new byte[2];
    public static byte[] CHANNELS = new byte[2];
    public static byte[] SamplesPerSec = new byte[4];
    public static byte[] AvgBytesPerSec = new byte[4];
    public static byte[] BlockAlign = new byte[2];
    public static byte[] BitsPerSample = new byte[2];
    public static byte[] Data = "data".getBytes();
    public static byte[] DataSize = new byte[4];
    public static boolean waveProduct(int audioLength, ByteArrayOutputStream byteArrayOutputStream, String outputFilePath){
        Step4_wave_product.DataSize = Step4_wave_product.revers(Step4_wave_product.intToBytes(audioLength));
        Step4_wave_product.RIFF_SIZE = Step4_wave_product.revers(Step4_wave_product.intToBytes(audioLength + 36 - 8));
        File waveFile = new File(outputFilePath);
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(waveFile);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            init();
            bufferedOutputStream.write(RIFF);
            bufferedOutputStream.write(RIFF_SIZE);
            bufferedOutputStream.write(RIFF_TYPE);
            bufferedOutputStream.write(FORMAT);
            bufferedOutputStream.write(FORMAT_SIZE);
            bufferedOutputStream.write(FORMAT_TAG);
            bufferedOutputStream.write(CHANNELS);
            bufferedOutputStream.write(SamplesPerSec);
            bufferedOutputStream.write(AvgBytesPerSec);
            bufferedOutputStream.write(BlockAlign);
            bufferedOutputStream.write(BitsPerSample);
            bufferedOutputStream.write(Data);
            bufferedOutputStream.write(DataSize);
            bufferedOutputStream.write(byteArrayOutputStream.toByteArray());
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
            return true;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
    }
    public static void init() {
        FORMAT_SIZE = new byte[]{(byte) 16, (byte) 0, (byte) 0, (byte) 0};
        byte[] tmp = revers(intToBytes(1));
        FORMAT_TAG = new byte[]{tmp[0], tmp[1]};
        CHANNELS = new byte[]{tmp[0], tmp[1]};
        SamplesPerSec = revers(intToBytes(16000));
        AvgBytesPerSec = revers(intToBytes(32000));
        tmp = revers(intToBytes(2));
        BlockAlign = new byte[]{tmp[0], tmp[1]};
        tmp = revers(intToBytes(16));
        BitsPerSample = new byte[]{tmp[0], tmp[1]};
    }
    public static byte[] revers(byte[] tmp) {
        byte[] reversed = new byte[tmp.length];
        for (int i = 0; i < tmp.length; i++) {
            reversed[i] = tmp[tmp.length - i - 1];
        }
        return reversed;
    }
    public static byte[] intToBytes(int num) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (num >> 24);
        bytes[1] = (byte) ((num >> 16) & 0x000000FF);
        bytes[2] = (byte) ((num >> 8) & 0x000000FF);
        bytes[3] = (byte) (num & 0x000000FF);
        return bytes;
    }
}

# 6、放置讯飞开放平台下载Linux/Windows中所带的资源,图-1
# 7、Linux代码基本类似,离线合成普通版,注意资源放置
package com.iflytek.service;
import com.iflytek.OfflineTtsMain;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
 
public interface Step1_tts_so extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  byte[]/Pointer,回调函数里此类型需用String来对应。
     * 4.int      对应  int
     * 5.无参     对应  void
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback,离线语音合成无回调
     */
    //加载dll动态库并实例化,从而使用其内部的方法
    Step1_tts_so INSTANCE = (Step1_tts_so) Native.loadLibrary(OfflineTtsMain.userPath+"res/libmsc.so", Step1_tts_so.class);
 
    //定义登录方法
    public int MSPLogin(String usr, String pwd, String params);
 
    //开始一次普通离线语音合成
    public String QTTSSessionBegin(String params, IntByReference errorCode);
 
    //写入需要合成的文本
    public int QTTSTextPut(String sessionID,String textString,int textLen,String params);
 
    //获取离线合成的音频
    public Pointer QTTSAudioGet(String sessionID, IntByReference audioLen, IntByReference synthStatus, IntByReference errorCode);
 
    //结束本次普通离线语音合成
    public int QTTSSessionEnd(String sessionID, String hints);
 
    //定义退出方法
    public int MSPLogout();
}

# 8、Linux代码基本类似,离线合成高品质,注意资源放置
package com.iflytek.service;
import com.iflytek.OfflineHighQualityTtsMain;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
 
public interface Step1_tts_so extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  byte[]/Pointer,回调函数里此类型需用String来对应。
     * 4.int      对应  int
     * 5.无参     对应  void
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback,离线语音合成无回调
     */
    //加载so动态库并实例化,从而使用其内部的方法
    Step1_tts_so INSTANCE = (Step1_tts_so) Native.loadLibrary(OfflineHighQualityTtsMain.userPath+"res/libmsc.so", Step1_tts_so.class);
 
    //定义登录方法
    public int MSPLogin(String usr, String pwd, String params);
 
    //开始一次高品质离线语音合成
    public String QTTSSessionBegin(String params, IntByReference errorCode);
 
    //写入需要合成的文本
    public int QTTSTextPut(String sessionID,String textString,int textLen,String params);
 
    //获取离线合成的音频
    public Pointer QTTSAudioGet(String sessionID, IntByReference audioLen, IntByReference synthStatus, IntByReference errorCode);
 
    //结束本次高品质离线语音合成
    public int QTTSSessionEnd(String sessionID, String hints);
 
    //定义退出方法
    public int MSPLogout();
}
# 9、普通版与高品质版对内存的消耗也不同,请根据实际所需进行选择

3、讯飞离线唤醒Windows/Linux

# 1、写调用主函数
package com.iflytek;
import com.iflytek.util.Step3_ivw_thread;
import com.iflytek.util.Step4_audioFormat;
import java.util.Scanner;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;
 
/**
 * 请注意!!!
 * 1.首选到控制台https://console.xfyun.cn/services/awaken下载唤醒的Windows MSC。
 * 2.下载的唤醒Windows MSC解压后,把bin目录下msc文件夹与dll文件拷贝到res目录下。
 * 3.最后请替换Step3_ivw_thread中的appid值,appid值在下载页面控制台可以看到。
 */
 
public class OfflineIvwMain {
	//录音相关参数
	public static AudioFormat audioFormat;
	public static TargetDataLine targetDataLine;
	public static void main(String[] args) throws Exception {
		System.out.println("y开始体验唤醒,n结束唤醒");
		Scanner input = new Scanner(System.in);
		String inputContent = input.next();
		long startTime = System.currentTimeMillis();
		if(inputContent.equals("y")){
			audioFormat = Step4_audioFormat.getAudioFormat(audioFormat);//构造具有线性 PCM 编码和给定参数的 AudioFormat。
			DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
			targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
			Step3_ivw_thread myThread=new Step3_ivw_thread();
			myThread.start();
			Scanner input_2 = new Scanner(System.in);
			String inputContent_2 = input_2.next();
			if(inputContent_2.equals("n")){
				targetDataLine.stop();
				targetDataLine.close();
			}
			System.out.println("唤醒操作持续:"+(System.currentTimeMillis()-startTime)/1000+"秒!");
			System.exit(0);
		}
	}
}
# 2、 根据文档用JAVA重写方法
package com.iflytek.service;
import com.iflytek.util.Step2_ivw_ntf_handler;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
 
public interface Step1_ivw_dll extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  Pointer或byte[]
     * 4.int      对应  int
     * 5.无参     对应  无参
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback
     */
    //加载dll动态库并实例化,从而使用其内部的方法
    Step1_ivw_dll INSTANCE = (Step1_ivw_dll) Native.loadLibrary
                             ("res/msc_x64.dll", Step1_ivw_dll.class);
 
    //定义登录方法    MSPLogin(const char *usr, const char *pwd, const char *params)
    public int MSPLogin(String usr, String pwd, String params);
 
    //定义开始方法    QIVWSessionbegin(const char *grammarList, const char *params, int *errorCode)
    public String QIVWSessionBegin(String grammarList, String params, IntByReference errorCode);
 
    //定义写音频方法  QIVWAudioWrite(const char *sessionID, const void *audioData, unsigned int audioLen, int audioStatus)
    public int QIVWAudioWrite(String sessionID, byte[] audioData, int audioLen, int audioStatus);
 
    //定义结束方法    QIVWSessionEnd(const char *sessionID, const char *hints)
    public int QIVWSessionEnd(String sessionID, String hints);
 
    //定义获取结果方法 QIVWRegisterNotify(const char *sessionID, ivw_ntf_handler msgProcCb, void *userData)
    public int QIVWRegisterNotify(String sessionID, Step2_ivw_ntf_handler msgProcCb, byte[] userData);
 
    //定义退出方法     MSPLogout()
    public int MSPLogout();
}
# 3、根据文档写回调函数
package com.iflytek.util;
import com.sun.jna.Callback;
 
public class Step2_ivw_ntf_handler implements Callback {
    //根据文档写回调方法
    public int cb_ivw_msg_proc(String sessionID, int msg, int param1, int param2,
                               String info, String userData) {
        System.out.println("..............................................");
        System.out.println("回调函数返回的唤醒结果:"+info);
        return 0;
    }
}
#  4、把调用步骤依次写到线程类
package com.iflytek.util;
import com.iflytek.OfflineIvwMain;
import com.iflytek.service.Step1_ivw_dll;
import com.sun.jna.ptr.IntByReference;
import javax.sound.sampled.AudioInputStream;
 
public class Step3_ivw_thread extends Thread{
	public void run() {
			//登录参数
			String lgi_param = "appid = 替换你的appid, work_dir = ./res";
			String ssb_param = "ivw_threshold=0:1450,sst=wakeup,ivw_shot_word=1,ivw_res_path =fo|res/ivw/wakeupresource.jet";
			int ret = Step1_ivw_dll.INSTANCE.MSPLogin(null, null, lgi_param);
			if (ret != 0) {//登录成功标志ret为0
				System.out.println("登录失败...请检查");
				System.exit(1);
			} else {
				System.out.println("请注意,唤醒语音需要根据控制台定义的唤醒词来进行唤醒...");
			}
 
			//开启会话
			IntByReference intByReference = new IntByReference(-100);
			String sessionId = Step1_ivw_dll.INSTANCE.QIVWSessionBegin(null, ssb_param, intByReference);
			if (intByReference.getValue() == 0) {//只有返回0为函数调用成功
				System.out.println("本次会话开启成功...,会话id为:" + sessionId);
			}
 
			int frameSize = 6400; //一帧的大小为6400B,其他的可能导致无法长时间唤醒
			int audioStatus = 1;//用来告知MSC音频发送是否完成
 
			//注册回调
			Step2_ivw_ntf_handler msgProcCb = new Step2_ivw_ntf_handler();//回调函数实例
			ret = Step1_ivw_dll.INSTANCE.QIVWRegisterNotify(sessionId, msgProcCb, null);
			if (ret == 0) {//返回为0则代表成功
				System.out.println("注册回调函数成功...");
			} else {
				System.out.println("注册函数返回的错误码" + ret);
			}
 
			//反复调用QIVWAudioWrite写音频方法,直到音频写完为止
			//long startTime=System.currentTimeMillis();
			try {
				while (true) {
					byte[] audioDataByteArray = new byte[frameSize];
					OfflineIvwMain.targetDataLine.open(OfflineIvwMain.audioFormat);
					OfflineIvwMain.targetDataLine.start();
					int len = new AudioInputStream(OfflineIvwMain.targetDataLine).read(audioDataByteArray);
					//long endTime=System.currentTimeMillis();
					if (len == -1) {//调用麦克风时候,这段将不会被执行...
						//||(endTime-startTime>60*1000)
						audioStatus = 4;//最后帧
						ret = Step1_ivw_dll.INSTANCE.QIVWAudioWrite(sessionId, "".getBytes(), 0, audioStatus);
						System.out.println("最后一帧返回的错误码:" + ret + ",即将执行退出...");
						break;  //文件读完,跳出循环
					} else {
						//反复调用
						ret = Step1_ivw_dll.INSTANCE.QIVWAudioWrite(sessionId, audioDataByteArray, len, audioStatus);
					}
					audioStatus = 2;//中间帧
					if (ret != 0) {
						System.err.println("出错了:" + ret);
					}
					Thread.sleep(200); //模拟人说话时间间隙
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
 
			//终止会话
			ret = Step1_ivw_dll.INSTANCE.QIVWSessionEnd(sessionId, "正常终止");
			if (ret == 0) {
				System.out.println("本次会话正常终止...");
			}
 
			//执行退出
			ret = Step1_ivw_dll.INSTANCE.MSPLogout();
			if (ret == 0) {
				System.out.println("正常退出...");
			}else{
				System.out.println("异常退出...");
			}
		}
}
# 5、 录音生成16K、16BIT单声道的音频流
package com.iflytek.util;
import javax.sound.sampled.AudioFormat;
 
public class Step4_audioFormat {
    //构造线程参数
    //16k采样率的16bit音频,一帧的大小为640B, 时长20ms
    /**
     sampleRate - 每秒样品数
     sampleSizeInBits - 每个样本中的位数
     channels - 通道数(1为mono,2为立体声等)
     signed - 表示数据是签名还是无符号
     bigEndian - 指示单个样本的数据是否以大字节顺序存储( false表示小端)
     */
    public static AudioFormat getAudioFormat(AudioFormat audioFormat) {
        audioFormat=new AudioFormat(16000F, 16, 1,true,false);
        // true,false 指示是以 big-endian 顺序还是以 little-endian 顺序存储音频数据。
        return audioFormat;//构造具有线性 PCM 编码和给定参数的 AudioFormat。
    }
}
# 6、放置讯飞开放平台下载Linux/Windows中所带的资源 图-1
# 7、 Linux代码基本类似,注意加载SO库就行和放置资源
package com.iflytek.service;
import com.iflytek.OfflineIvwMain;
import com.iflytek.util.Step2_ivw_ntf_handler;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
 
public interface Step1_ivw_so extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  Pointer
     * 4.int      对应  int
     * 5.无参     对应  无参
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback
     * 7.Linux设置程序共享库位置,否则会话时会报错25000
     *   export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/SoIvw/res
     *   注意:每个版本都有两个so库,libmsc.so、libw_ivw.so
     */
    //加载so动态库并实例化,从而使用其内部的方法
    Step1_ivw_so INSTANCE = (Step1_ivw_so) Native.loadLibrary
            (OfflineIvwMain.userPath+"res/libmsc.so", Step1_ivw_so.class);
 
    //定义登录方法    MSPLogin(const char *usr, const char *pwd, const char *params)
    public int MSPLogin(String usr, String pwd, String params);
 
    //定义开始方法    QIVWSessionbegin(const char *grammarList, const char *params, int *errorCode)
    public String QIVWSessionBegin(String grammarList, String params, IntByReference errorCode);
 
    //定义写音频方法  QIVWAudioWrite(const char *sessionID, const void *audioData, unsigned int audioLen, int audioStatus)
    public int QIVWAudioWrite(String sessionID, byte[] audioData, int audioLen, int audioStatus);
 
    //定义获取结果方法 QIVWRegisterNotify(const char *sessionID, ivw_ntf_handler msgProcCb, void *userData)
    public int QIVWRegisterNotify(String sessionID, Step2_ivw_ntf_handler msgProcCb, Pointer userData);
 
    //定义结束方法    QIVWSessionEnd(const char *sessionID, const char *hints)
    public int QIVWSessionEnd(String sessionID, String hints);
 
    //定义退出方法     MSPLogout()
    public int MSPLogout();
}

 

 4、讯飞离线命令词识别Windows/Linux

# 1、离线命令词识别调用主函数
package com.iflytek;
import com.iflytek.util.Step2_asr_thread;
import com.iflytek.util.Step3_audioFormat;
import java.util.Scanner;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;
 
/**
 * 请注意!!!
 * 1.首先到控制台https://console.xfyun.cn/services/mlcsb下载离线命令词识别的Windows MSC。
 * 2.下载的离线命令词识别Windows MSC解压后,把bin目录下msc文件夹、dll文件、call.bnf文件拷贝到res目录下。
 * 3.最后请替换Step2_ars_thread中的appid值,appid值在下载页面控制台可以看到。
 */
 
public class OfflineAsrMain {
	//录音相关参数
	public static AudioFormat audioFormat;
	public static TargetDataLine targetDataLine;
	public static void main(String[] args) throws Exception {
		System.out.println("y开始体验离线命令词识别,n结束离线命令词识别");
		Scanner input = new Scanner(System.in);
		String inputContent = input.next();
		long startTime = System.currentTimeMillis();
		if(inputContent.equals("y")){
			audioFormat = Step3_audioFormat.getAudioFormat(audioFormat);//构造具有线性 PCM 编码和给定参数的 AudioFormat。
			DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
			targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
			Step2_asr_thread myThread=new Step2_asr_thread();
			myThread.start();
			Scanner input_2 = new Scanner(System.in);
			String inputContent_2 = input_2.next();
			if(inputContent_2.equals("n")){
				targetDataLine.stop();
				targetDataLine.close();
			}
			System.out.println("离线命令词识别操作持续:"+(System.currentTimeMillis()-startTime)/1000+"秒!");
			System.exit(0);
		}
	}
}
# 2、根据MSC文档用JAVA重写方法
package com.iflytek.service;
import com.iflytek.util.Step1_grammar_callback;
import com.iflytek.util.Step1_lexicon_callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
 
public interface Step1_asr_dll extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  byte[],回调函数里此类型也可以用String来对应。
     * 4.int      对应  int
     * 5.无参     对应  void
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback
     */
    //加载dll动态库并实例化,从而使用其内部的方法
    Step1_asr_dll INSTANCE = (Step1_asr_dll) Native.loadLibrary
                             ("res/msc_x64.dll", Step1_asr_dll.class);
 
    //定义登录方法
    public int MSPLogin(String usr, String pwd, String params);
 
    //开始一次语音识别。
    public String QISRSessionBegin(String grammarList,String params,IntByReference errorCode);
 
    //写入本次识别的音频
    public int QISRAudioWrite(String sessionID, byte[] byteArrayAudioData,int waveLen,int audioStatus, IntByReference epStatus,IntByReference recogStatus);
 
    //获取识别结果。
    public String QISRGetResult(String sessionID,IntByReference rsltStatus,int waitTime, IntByReference errorCode);
 
    //结束本次语音识别。
    public int QISRSessionEnd(String sessionID,String hints);
 
    //获取当次语音识别信息,如上行流量、下行流量等
    public int QISRGetParam(String sessionID,String paramName,String paramValue, IntByReference valueLen);
 
    //构建语法,生成语法ID。有回调
    public int QISRBuildGrammar(String grammarType, String grammarContent, int grammarLength, String params, Step1_grammar_callback grammarCallBack, byte[] userData);
 
    //更新本地语法词典。有回调
    public int QISRUpdateLexicon(String lexiconName, String lexiconContent, int lexiconLength, String params, Step1_lexicon_callback lexiconCallback, byte[] userData);
 
    //定义退出方法
    public int MSPLogout();
}
# 3、 构建语法回调函数
package com.iflytek.util;
import com.sun.jna.Callback;
 
public class Step1_grammar_callback implements Callback {
    //根据文档写回调方法
    public int build_grm_cb(int errorCode,String info, String userData) {
        System.out.println("构建语法返回的ID信息...:"+info+"错误码"+errorCode+"\n");
        return 0;
    }
}
# 4、更新词典回调函数
package com.iflytek.util;
import com.sun.jna.Callback;
 
public class Step1_lexicon_callback implements Callback {
    //根据文档写回调方法
    public int LexiconCallBack(int errorCode, String info, String userData) {
        System.out.println("更新词典返回的信息...:"+info+"错误码:"+errorCode+"\n");
        return 0;
    }
}
# 5、把调用步骤依次写进线程类
package com.iflytek.util;
import com.iflytek.OfflineAsrMain;
import com.iflytek.service.Step1_asr_dll;
import com.sun.jna.ptr.IntByReference;
import javax.sound.sampled.AudioInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
 
public class Step2_asr_thread extends Thread{
	public void run() {
		while (true) {
			//登录参数
			String login_config = "appid = 替换你的appid, work_dir = ./res";
			//第一个参数为用户名,第二个参数为密码,传null即可
			int ret = Step1_asr_dll.INSTANCE.MSPLogin(null, null, login_config);
			if (ret != 0) {//登录成功标志ret为0
				System.out.println("登录失败...请检查"+ret);
				System.exit(1);
			} else {
				//System.out.println("请注意,离线命令词call.bnf可以根据语法自定义...");
			}
 
			//读取call.bnf的内容
			FileInputStream fileInputStream = null;
			String grammarContent = "";
			try {
				fileInputStream = new FileInputStream("./res/call.bnf");
				InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
				BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
				String temp = "";
				while ((temp = bufferedReader.readLine()) != null) {
					grammarContent = grammarContent + temp + "\n";
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			//System.out.println("语法内容:\n" + grammarContent);
 
			//构建语法
			Step1_grammar_callback step2_grammar_callback = new Step1_grammar_callback();
			String params = "engine_type = local,asr_res_path = fo|res/asr/common.jet,sample_rate = 16000,grm_build_path = res/asr/GrmBuilld_x64";
			ret = Step1_asr_dll.INSTANCE.QISRBuildGrammar("bnf", grammarContent, grammarContent.getBytes().length, params, step2_grammar_callback, null);
			if (ret == 0) {
				//System.out.println("构建语法成功...");
			} else {
				System.out.println("构建语法失败:" + ret);
			}
 
			//更新本地语法词典
			/*String lexiconName = "enter";
			String lex_content = "登录软件";
			String lexParams = "engine_type=local,asr_res_path = fo|res/asr/common.jet, sample_rate = 16000,grm_build_path =res/asr/GrmBuilld_x64, grammar_list =call";
			Step3_lexicon_callback step3_lexicon_callback = new Step3_lexicon_callback();
			ret = Step1_asr_dll.INSTANCE.QISRUpdateLexicon(lexiconName, lex_content, lex_content.getBytes().length, lexParams, step3_lexicon_callback, null);
			if (ret == 0) {
				//System.out.println("更新本地语法词典成功...");
			} else {
				System.out.println("更新本地语法词典失败:" + ret);
			}*/
 
			//开始一次语音识别
			IntByReference errorCode = new IntByReference(-100);
			params = "vad_bos =4000 ,vad_eos = 10000,engine_type = local,asr_res_path = fo|res/asr/common.jet, sample_rate = 16000,grm_build_path = res/asr/GrmBuilld_x64, local_grammar = call,result_type = json, result_encoding = UTF8";
			String session_id = Step1_asr_dll.INSTANCE.QISRSessionBegin(null, params, errorCode);
			if (errorCode.getValue() == 0) {//只有返回0为函数调用成功
				System.out.println("本次会话开启成功...,会话id为:" + session_id);
			} else {
				System.out.println("本次会话开启失败:" + errorCode.getValue());
			}
 
			//写入识别的音频
			try {
				//给构建语法、更新本地语法词典点时间
				Thread.sleep(100);
				System.err.println("\033[43;34;4m" + "请开始说出命令..." + "\033[0m");
				//间隔400ms给用户反映时间
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			IntByReference epStatus = new IntByReference(-100);
			IntByReference recogStatus = new IntByReference(-100);
			//16k采样率的16位音频,一帧的大小为640Byte(来自Windows SDK的说明)
			int frameSize = 640;
			//用来告知MSC音频发送是否完成
			int audioStatus = 1;
			//反复调用QISRAudioWrite写音频方法,直到音频写完为止
			//long startTime=System.currentTimeMillis();
			try {
				final byte[] audioDataByteArray = new byte[frameSize];
				while (true) {
					OfflineAsrMain.targetDataLine.open(OfflineAsrMain.audioFormat);
					OfflineAsrMain.targetDataLine.start();
					int len = new AudioInputStream(OfflineAsrMain.targetDataLine).read(audioDataByteArray);
					//long endTime=System.currentTimeMillis();//||endTime-startTime>60000
					if (len == -1 || epStatus.getValue() == 3) {//调用麦克风时候,len == -1将不会被执行...
						//||(endTime-startTime>60*1000)
						audioStatus = 4;//最后帧
						ret = Step1_asr_dll.INSTANCE.QISRAudioWrite(session_id, audioDataByteArray, len, audioStatus, epStatus, recogStatus);
						if (ret == 0) {
							//System.out.println("最后一帧音频写入正常");
						} else {
							System.out.println("最后一帧音频写入异常:" + ret);
						}
						Thread.sleep(1500);
						break;  //文件读完,跳出循环
					} else {
						//反复调用
						ret = Step1_asr_dll.INSTANCE.QISRAudioWrite(session_id, audioDataByteArray, len, audioStatus, epStatus, recogStatus);
					}
					audioStatus = 2;//中间帧
					if (ret == 0) {
						//System.out.println("音频写入正常");
					} else {
						System.out.println("音频写入异常:" + ret);
					}
					// 如果是实时采集音频,可以省略此操作。5KB 大小的16KPCM 持续的时间是160 毫秒
					//Thread.sleep(160);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
 
			//获取识别结果
			IntByReference rsltStatus = new IntByReference(-100);
			String grammarResult = Step1_asr_dll.INSTANCE.QISRGetResult(session_id, rsltStatus, 0, errorCode);
			if(grammarResult!=null){
				System.out.println("命令词识别结果:" + grammarResult);
			}
 
			//终止会话
			ret = Step1_asr_dll.INSTANCE.QISRSessionEnd(session_id, "正常终止");
			if (ret == 0) {
				//System.out.println("本次会话正常终止...");
			} else {
				System.out.println("本次会话异常终止...");
			}
 
			//执行退出
			ret = Step1_asr_dll.INSTANCE.MSPLogout();
			if (ret == 0) {
				//System.out.println("正常退出...");
			} else {
				System.out.println("异常退出...");
			}
		}
	}
}
# 6、录音生成16K、16BIT单声道的音频流
package com.iflytek.util;
import javax.sound.sampled.AudioFormat;
 
public class Step3_audioFormat {
    //构造线程参数
    //16k采样率的16bit音频,一帧的大小为640B, 时长20ms
    /**
     sampleRate - 每秒样品数
     sampleSizeInBits - 每个样本中的位数
     channels - 通道数(1为mono,2为立体声等)
     signed - 表示数据是签名还是无符号
     bigEndian - 指示单个样本的数据是否以大字节顺序存储( false表示小端)
     */
    public static AudioFormat getAudioFormat(AudioFormat audioFormat) {
        audioFormat=new AudioFormat(16000F, 16,
                                   1,true,false);
        // true,false 指示是以 big-endian 顺序还是以 little-endian 顺序存储音频数据。
        return audioFormat;//构造具有线性 PCM 编码和给定参数的 AudioFormat。
    }
}
# 7、放置讯飞开放平台下载Linux/Windows中所带的资源,图-1
# 8、Linux代码基本类似,注意加载SO库就行和放置资源
package com.iflytek.service;
import com.iflytek.OfflineAsrMain;
import com.iflytek.util.Step1_grammar_callback;
import com.iflytek.util.Step1_lexicon_callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
 
public interface Step1_asr_so extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  byte[],回调函数里此类型需用String来对应。
     * 4.int      对应  int
     * 5.无参     对应  void
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback
     */
    //加载so动态库并实例化,从而使用其内部的方法
    Step1_asr_so INSTANCE = (Step1_asr_so) Native.loadLibrary
            (OfflineAsrMain.userPath+"res/libmsc.so", Step1_asr_so.class);
 
    //定义登录方法
    public int MSPLogin(String usr, String pwd, String params);
 
    //开始一次语音识别。
    public String QISRSessionBegin(String grammarList,String params,IntByReference errorCode);
 
    //写入本次识别的音频
    public int QISRAudioWrite(String sessionID, byte[] byteArrayAudioData,int waveLen,int audioStatus, IntByReference epStatus,IntByReference recogStatus);
 
    //获取识别结果。
    public String QISRGetResult(String sessionID,IntByReference rsltStatus,int waitTime, IntByReference errorCode);
 
    //结束本次语音识别。
    public int QISRSessionEnd(String sessionID,String hints);
 
    //获取当次语音识别信息,如上行流量、下行流量等
    public int QISRGetParam(String sessionID,String paramName,String paramValue, IntByReference valueLen);
 
    //构建语法,生成语法ID。有回调
    public int QISRBuildGrammar(String grammarType, String grammarContent, int grammarLength, String params, Step1_grammar_callback grammarCallBack, byte[] userData);
 
    //更新本地语法词典。有回调
    public int QISRUpdateLexicon(String lexiconName, String lexiconContent, int lexiconLength, String params, Step1_lexicon_callback lexiconCallback, byte[] userData);
 
    //定义退出方法
    public int MSPLogout();
}

 

 5、顺丰运单查询

1、目的:批量调用顺丰运单路由接口,更新最新物流状态
【1】到顺丰开放平台-服务与支持-开放规范-API-SDK使用-直接下载SDK
【2】开通正式接口必须要完成沙盒的3次成功调用。
2、这里有个坑,沙盒环境也必须替换正式顾客编码和校验码
【1】如果不替换,永远也通不过测试,无法开通正式环境。
3、需要上传电子面单
【1】这里可以在帮助中心提问,跳过审核
4、成功调用后就需要对返回的json数据进行解析
【1】这里又有一个坑,就是json不太规范,需要写两个json解析类,分两次解析
【2】详析代码如下:
class JsonParse{
    public String apiResultData;
}
class JsonParse2{
    public MsgData msgData;
}
class MsgData{
    List<RouteResps> routeResps;
}
class RouteResps{
    public String mailNo;
    List<Routes> routes;
}
class Routes{
    public String acceptTime;
    public String remark;
    public int opCode;
}
 JsonParse jsonParse=gson.fromJson(result,JsonParse.class);
 System.out.println("===返回结果:" +jsonParse.apiResultData);
 JsonParse2 jsonParse2=gson.fromJson(jsonParse.apiResultData,JsonParse2.class);
5、需要结合官方文档,来判断opCode的值对应的状态,图-1
6、接口调用限制每次传10个运单,但是我每次要查2000多个。
【1】所以用循环加逻辑判断来分批调用顺丰的接口
 @RequestMapping("updateAhSfTableBySfInterface")
    public ModelAndView updateAhSfTableBySfInterface(AhSfTable ahSfTable) throws Exception{
        ModelAndView mv=new ModelAndView();
        List<AhSfTable> tempAhSfTableList=bigMapper.selectAhSfTableByLastLogisticsStatus();
        if(tempAhSfTableList.size()>0){
            int needWorkTimes=0;
            List<SfInterface> sfInterfaceList=new ArrayList<SfInterface>();
            if(tempAhSfTableList.size()%10==0){
                //说明刚好可以调整数次接口
                needWorkTimes=tempAhSfTableList.size()/10;
                //开始分批调用
                for(int i=0;i<needWorkTimes;i++){
                    String tempJsonNeed="";
                    for(int j=10*i;j<10*(i+1);j++){
                        tempJsonNeed=tempJsonNeed+"\""+tempAhSfTableList.get(j).getBillCode()+"\",";
                    }
                    tempJsonNeed="["+tempJsonNeed.substring(0,tempJsonNeed.length()-1)+"]";
                    sfInterfaceList=CallExpressAPIUtil.doSfInterfaceQuery(sfInterfaceList,tempJsonNeed);
                }
            }else{
                //说明有剩余,设置为+1次
                needWorkTimes=tempAhSfTableList.size()/10+1;
                //开始分批调用
                for(int i=0;i<needWorkTimes;i++){
                    String tempJsonNeed="";
                    for(int j=10*i;j<10*(i+1);j++){
                        //最后一次会越界,所以加个判断
                        if(j<tempAhSfTableList.size()){
                            tempJsonNeed=tempJsonNeed+"\""+tempAhSfTableList.get(j).getBillCode()+"\",";
                        }
                    }
                    tempJsonNeed="["+tempJsonNeed.substring(0,tempJsonNeed.length()-1)+"]";
                    sfInterfaceList=CallExpressAPIUtil.doSfInterfaceQuery(sfInterfaceList,tempJsonNeed);
                }
            }
            //System.out.println(sfInterfaceList.size());
            bigMapper.updateAhSfTableLastLogisticsStatusByBillCode(sfInterfaceList);
           /* for(int i=0;i<sfInterfaceList.size();i++){
                System.out.println(sfInterfaceList.get(i).getLastLogisticsStatus());
            }*/
        }
        ahSfTable.setOperateResultInfo("更新完成...");
        mv.addObject("ahSfTable",ahSfTable);
        return mv;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值