zoukankan      html  css  js  c++  java
  • Java 百度翻译 API 中文转英文接入

    Java 百度翻译 API 中文转英文接入

    业务上遇到了语言国际化的需求,需要将 中文的 json 字符串翻译成英文,通过百度翻译 API 接口来实现翻译功能。

    1、平台认证

    登录百度翻译开放平台,找到通用翻译模块,提交申请。

    申请链接:http://api.fanyi.baidu.com/product/11

    申请通过后,就能直接使用了,默认为标准版,完全免费:

    image-20210928105859820

    2、Java demo 配置

    翻译开放平台非常友好,提供了许多常用语言的 demo 下载,稍微修改下便能使用了。

    页面下载链接: http://api.fanyi.baidu.com/doc/21

    image-20210928110303954

    demo 配置好 appid密钥,运行便能看到控制台中文成功翻译成了英文:

    image-20210928111958694

    3、封装接口

    我的目标是将 一长串的中文 json 翻译成英文 json, 上面的 demo 是满足不了需求的,可以创建一个 springboot 项目,将 demo 代码迁移到项目中,封装一个接口实现业务需求。

    项目结构如下:

    image-20210928113040093

    3.1、自定义接口

    先引入 fastJson 依赖:

    <!--fastJson-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.70</version>
    </dependency>
    

    接口参数接收一长串的中文 json ,翻译完成后返回英文 json:

    3.1.1、直接创建线程版本
    package com.lin.translate.controller;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.lin.translate.config.TransApi;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.util.List;
    import java.util.Map;
    
    @Controller
    @RequestMapping("/com/lin")
    public class TranslateController {
    
        // 在平台申请的APP_ID 详见 http://api.fanyi.baidu.com/api/trans/product/desktop?req=developer
        private static final String APP_ID = "";
        private static final String SECURITY_KEY = "";
    
        @GetMapping("/translate")
        @ResponseBody
        public Map<String, Map<String, String>> toTranslate(@RequestBody Map<String, Map<String, String>> map) throws InterruptedException {
            TransApi api = new TransApi(APP_ID, SECURITY_KEY);
            for(String  key : map.keySet()) {
                Map<String, String> childMap = map.get(key);
                StringBuilder builder = new StringBuilder();
                for (String childKey : childMap.keySet()) {
                    //需要翻译的中文
                    builder.append(childMap.get(childKey)).append("
    ");
                }
                //创建线程
                Thread thread = new Thread() {
                    @Override
                    public void run() {
                        String result = api.getTransResult(builder.toString(), "auto", "en");
                        System.out.println(result);
                        //转成map
                        Map<String, String> mapResult = JSON.parseObject(result, Map.class);
                        List<Map<String, String>> transResult = (List<Map<String, String>>)JSONArray.parse(JSON.toJSONString(mapResult.get("trans_result")));
                        int i = 0;
                        for (String childKey : childMap.keySet()) {
                            //获取翻译结果
                            String transQuery = transResult.get(i).get("dst");
                            try {
                                //解码
                                transQuery= URLDecoder.decode(transQuery,"utf-8");
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                            childMap.put(childKey, transQuery);
                            i++;
                        }
                        try {
                            //睡眠一秒
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                thread.start();
                //主线程阻塞,等待子线程结束
                thread.join();
            }
            return map;
        }
    }
    
    
    3.1.2、线程池版本
    package com.lin.translate.controller;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.lin.translate.config.TransApi;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.*;
    
    @Controller
    @RequestMapping("/com/lin")
    public class ExecutorController {
    
        // 在平台申请的APP_ID 详见 http://api.fanyi.baidu.com/api/trans/product/desktop?req=developer
        private static final String APP_ID = "";
        private static final String SECURITY_KEY = "";
    
        @GetMapping("/executorTranslate")
        @ResponseBody
        public Map<String, Map<String, String>> toTranslate(@RequestBody Map<String, Map<String, String>> map) throws InterruptedException {
            TransApi api = new TransApi(APP_ID, SECURITY_KEY);
            //创建线程池,核心线程1,最大线程数10,存货时间1分钟,任务队列5,默认的线程工厂,拒绝策略为拒绝并抛出异常
            ExecutorService executorService = new ThreadPoolExecutor(1, 10, 1, TimeUnit.MINUTES,
                    new ArrayBlockingQueue<>(5, true), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
            for (String key : map.keySet()) {
                Map<String, String> childMap = map.get(key);
                StringBuilder builder = new StringBuilder();
                for (String childKey : childMap.keySet()) {
                    //需要翻译的中文
                    builder.append(childMap.get(childKey)).append("
    ");
                }
                //执行线程
                executorService.execute(() -> {
                    String result = api.getTransResult(builder.toString(), "auto", "en");
                    System.out.println("result:" + result);
                    //转成map
                    Map<String, String> mapResult = JSON.parseObject(result, Map.class);
                    List<Map<String, String>> transResult = (List<Map<String, String>>) JSONArray.parse(JSON.toJSONString(mapResult.get("trans_result")));
                    int i = 0;
                    for (String childKey : childMap.keySet()) {
                        //获取翻译结果
                        String transQuery = transResult.get(i).get("dst");
                        try {
                            //解码
                            transQuery = URLDecoder.decode(transQuery, "utf-8");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                        childMap.put(childKey, transQuery);
                        i++;
                    }
                });
                //线程池等待时间,这里即阻塞2秒
                executorService.awaitTermination(2, TimeUnit.SECONDS);
            }
            //任务执行完成后关闭线程池
            executorService.shutdown();
            return map;
        }
    }
    

    3.2、demo 配置类代码

    HttpGet 类代码如下:

    package com.baidu.translate.demo;
    
    import java.io.BufferedReader;
    import java.io.Closeable;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLEncoder;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.Map;
    
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    class HttpGet {
        protected static final int SOCKET_TIMEOUT = 10000; // 10S
        protected static final String GET = "GET";
    
        public static String get(String host, Map<String, String> params) {
            try {
                // 设置SSLContext
                SSLContext sslcontext = SSLContext.getInstance("TLS");
                sslcontext.init(null, new TrustManager[] { myX509TrustManager }, null);
    
                String sendUrl = getUrlWithQueryString(host, params);
    
                // System.out.println("URL:" + sendUrl);
    
                URL uri = new URL(sendUrl); // 创建URL对象
                HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
                if (conn instanceof HttpsURLConnection) {
                    ((HttpsURLConnection) conn).setSSLSocketFactory(sslcontext.getSocketFactory());
                }
    
                conn.setConnectTimeout(SOCKET_TIMEOUT); // 设置相应超时
                conn.setRequestMethod(GET);
                int statusCode = conn.getResponseCode();
                if (statusCode != HttpURLConnection.HTTP_OK) {
                    System.out.println("Http错误码:" + statusCode);
                }
    
                // 读取服务器的数据
                InputStream is = conn.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                StringBuilder builder = new StringBuilder();
                String line = null;
                while ((line = br.readLine()) != null) {
                    builder.append(line);
                }
    
                String text = builder.toString();
    
                close(br); // 关闭数据流
                close(is); // 关闭数据流
                conn.disconnect(); // 断开连接
    
                return text;
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public static String getUrlWithQueryString(String url, Map<String, String> params) {
            if (params == null) {
                return url;
            }
    
            StringBuilder builder = new StringBuilder(url);
            if (url.contains("?")) {
                builder.append("&");
            } else {
                builder.append("?");
            }
    
            int i = 0;
            for (String key : params.keySet()) {
                String value = params.get(key);
                if (value == null) { // 过滤空的key
                    continue;
                }
    
                if (i != 0) {
                    builder.append('&');
                }
    
                builder.append(key);
                builder.append('=');
                builder.append(encode(value));
    
                i++;
            }
    
            return builder.toString();
        }
    
        protected static void close(Closeable closeable) {
            if (closeable != null) {
                try {
                    closeable.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 对输入的字符串进行URL编码, 即转换为%20这种形式
         * 
         * @param input 原文
         * @return URL编码. 如果编码失败, 则返回原文
         */
        public static String encode(String input) {
            if (input == null) {
                return "";
            }
    
            try {
                return URLEncoder.encode(input, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
    
            return input;
        }
    
        private static TrustManager myX509TrustManager = new X509TrustManager() {
    
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
    
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
    
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }
        };
    }
    

    MD5 类代码如下:

    package com.lin.translate.config;
    
    import java.io.*;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    /**
     * MD5编码相关的类
     * 
     * @author wangjingtao
     * 
     */
    public class MD5 {
        // 首先初始化一个字符数组,用来存放每个16进制字符
        private static final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
                'e', 'f' };
    
        /**
         * 获得一个字符串的MD5值
         * 
         * @param input 输入的字符串
         * @return 输入字符串的MD5值
         * 
         */
        public static String md5(String input) {
            if (input == null) {
                return null;
            }
    
            try {
                // 拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”)
                MessageDigest messageDigest = MessageDigest.getInstance("MD5");
                // 输入的字符串转换成字节数组
                byte[] inputByteArray = input.getBytes("utf-8");
                // inputByteArray是输入字符串转换得到的字节数组
                messageDigest.update(inputByteArray);
                // 转换并返回结果,也是字节数组,包含16个元素
                byte[] resultByteArray = messageDigest.digest();
                // 字符数组转换成字符串返回
                return byteArrayToHex(resultByteArray);
            } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 获取文件的MD5值
         * 
         * @param file
         * @return
         */
        public static String md5(File file) {
            try {
                if (!file.isFile()) {
                    System.err.println("文件" + file.getAbsolutePath() + "不存在或者不是文件");
                    return null;
                }
    
                FileInputStream in = new FileInputStream(file);
    
                String result = md5(in);
    
                in.close();
    
                return result;
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        public static String md5(InputStream in) {
    
            try {
                MessageDigest messagedigest = MessageDigest.getInstance("MD5");
    
                byte[] buffer = new byte[1024];
                int read = 0;
                while ((read = in.read(buffer)) != -1) {
                    messagedigest.update(buffer, 0, read);
                }
    
                in.close();
    
                String result = byteArrayToHex(messagedigest.digest());
    
                return result;
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        private static String byteArrayToHex(byte[] byteArray) {
            // new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
            char[] resultCharArray = new char[byteArray.length * 2];
            // 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
            int index = 0;
            for (byte b : byteArray) {
                resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
                resultCharArray[index++] = hexDigits[b & 0xf];
            }
    
            // 字符数组组合成字符串返回
            return new String(resultCharArray);
    
        }
    }
    

    TransApi 类代码如下:

    package com.lin.translate.config;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class TransApi {
        private static final String TRANS_API_HOST = "http://api.fanyi.baidu.com/api/trans/vip/translate";
    
        private String appid;
        private String securityKey;
    
        public TransApi(String appid, String securityKey) {
            this.appid = appid;
            this.securityKey = securityKey;
        }
    
        public String getTransResult(String query, String from, String to) {
            Map<String, String> params = buildParams(query, from, to);
            return HttpGet.get(TRANS_API_HOST, params);
        }
    
        private Map<String, String> buildParams(String query, String from, String to) {
            Map<String, String> params = new HashMap<String, String>();
            params.put("q", query);
            params.put("from", from);
            params.put("to", to);
    
            params.put("appid", appid);
    
            // 随机数
            String salt = String.valueOf(System.currentTimeMillis());
            params.put("salt", salt);
    
            // 签名
            String src = appid + query + salt + securityKey; // 加密前的原文
            params.put("sign", MD5.md5(src));
    
            return params;
        }
    }
    

    3.3、结果示例

    原中文 json:

    {
      "login": {
        "login": "登录",
        "loginLoading": "登录中...",
        "account": "账号",
        "password": "密码",
        "lang": "语言",
        "setAddress": "设置服务地址",
        "more": "更多"
      },
      "mDns": {
        "local": "局域网",
        "localText": "内的XYMERP服务",
        "useAddress": "当前设置的地址",
        "addressUnAvailable": "无法连接此服务器",
        "setAddressTips": "未设置服务地址,立刻设置"
      }
    }
    

    翻译后的英文 json:

    {
        "login": {
            "login": "Sign in",
            "loginLoading": "Logging in",
            "account": "account number",
            "password": "password",
            "lang": "language",
            "setAddress": "Set service address",
            "more": "more"
        },
        "mDns": {
            "local": "LAN",
            "localText": "Xymerp service in",
            "useAddress": "Currently set address",
            "addressUnAvailable": "Unable to connect to this server",
            "setAddressTips": "Service address not set, set now"
        }
    }
    

    以上结果满足我的需求了,不满足你们需求的就稍微修改下吧。

    自我控制是最强者的本能-萧伯纳
  • 相关阅读:
    ZOJ2913Bus Pass(BFS+set)
    HDU1242 Rescue(BFS+优先队列)
    转(havel 算法)
    ZOJ3761(并查集+树的遍历)
    ZOJ3578(Matrix)
    HDU1505
    ZOJ3574(归并排序求逆数对)
    VUE-脚手架搭建
    VUE脚手架搭建
    VUE-node.js
  • 原文地址:https://www.cnblogs.com/CF1314/p/15347212.html
Copyright © 2011-2022 走看看