序言:最近接触一个新的PLM系统,但是没有中文,查看了官网提供了汉化包,但是按照教程安装时发现没用,通过检查汉化文件发现里面都是空的,只是提供了一个模板,真坑!手动汉化是不可能的,所以决定写一个小工具进行xml配置文件的汉化。这里只讲解翻译过程。
至于为什么用网易有道的api,因为Google和Microsoft注册需要信用卡,所以不考虑了。
工具类
AuthV3Util.java
package com.youdao.aicloud.translate.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.UUID;
public class AuthV3Util {
/**
* 添加鉴权相关参数 -
* appKey : 应用ID
* salt : 随机值
* curtime : 当前时间戳(秒)
* signType : 签名版本
* sign : 请求签名
*
* @param appKey 您的应用ID
* @param appSecret 您的应用密钥
* @param paramsMap 请求参数表
*/
public static void addAuthParams(String appKey, String appSecret, Map<String, String[]> paramsMap)
throws NoSuchAlgorithmException {
String[] qArray = paramsMap.get("q");
if (qArray == null) {
qArray = paramsMap.get("img");
}
StringBuilder q = new StringBuilder();
for (String item : qArray) {
q.append(item);
}
String salt = UUID.randomUUID().toString();
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
String sign = calculateSign(appKey, appSecret, q.toString(), salt, curtime);
paramsMap.put("appKey", new String[]{appKey});
paramsMap.put("salt", new String[]{salt});
paramsMap.put("curtime", new String[]{curtime});
paramsMap.put("signType", new String[]{"v3"});
paramsMap.put("sign", new String[]{sign});
}
/**
* 计算鉴权签名 -
* 计算方式 : sign = sha256(appKey + input(q) + salt + curtime + appSecret)
*
* @param appKey 您的应用ID
* @param appSecret 您的应用密钥
* @param q 请求内容
* @param salt 随机值
* @param curtime 当前时间戳(秒)
* @return 鉴权签名sign
*/
public static String calculateSign(String appKey, String appSecret, String q, String salt, String curtime)
throws NoSuchAlgorithmException {
String strSrc = appKey + getInput(q) + salt + curtime + appSecret;
return encrypt(strSrc);
}
private static String encrypt(String strSrc) throws NoSuchAlgorithmException {
byte[] bt = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(bt);
byte[] bts = md.digest();
StringBuilder des = new StringBuilder();
for (byte b : bts) {
String tmp = (Integer.toHexString(b & 0xFF));
if (tmp.length() == 1) {
des.append("0");
}
des.append(tmp);
}
return des.toString();
}
private static String getInput(String input) {
if (input == null) {
return null;
}
String result;
int len = input.length();
if (len <= 20) {
result = input;
} else {
String startStr = input.substring(0, 10);
String endStr = input.substring(len - 10, len);
result = startStr + len + endStr;
}
return result;
}
}
AuthV4Util.java
package com.youdao.aicloud.translate.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.UUID;
public class AuthV4Util {
/**
* 添加鉴权相关参数 -
* appKey : 应用ID
* salt : 随机值
* curtime : 当前时间戳(秒)
* signType : 签名版本
* sign : 请求签名
*
* @param appKey 您的应用ID
* @param appSecret 您的应用密钥
* @param paramsMap 请求参数表
*/
public static void addAuthParams(String appKey, String appSecret, Map<String, String[]> paramsMap)
throws NoSuchAlgorithmException {
String salt = UUID.randomUUID().toString();
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
String sign = calculateSign(appKey, appSecret, salt, curtime);
paramsMap.put("appKey", new String[]{appKey});
paramsMap.put("salt", new String[]{salt});
paramsMap.put("curtime", new String[]{curtime});
paramsMap.put("signType", new String[]{"v4"});
paramsMap.put("sign", new String[]{sign});
}
/**
* 计算鉴权签名 -
* 计算方式 : sign = sha256(appKey + salt + curtime + appSecret)
*
* @param appKey 您的应用ID
* @param appSecret 您的应用密钥
* @param salt 随机值
* @param curtime 当前时间戳(秒)
* @return 鉴权签名sign
*/
public static String calculateSign(String appKey, String appSecret, String salt, String curtime)
throws NoSuchAlgorithmException {
String strSrc = appKey + salt + curtime + appSecret;
return encrypt(strSrc);
}
private static String encrypt(String strSrc) throws NoSuchAlgorithmException {
byte[] bt = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(bt);
byte[] bts = md.digest();
StringBuilder des = new StringBuilder();
for (byte b : bts) {
String tmp = (Integer.toHexString(b & 0xFF));
if (tmp.length() == 1) {
des.append("0");
}
des.append(tmp);
}
return des.toString();
}
}
FileUtil.java
package com.youdao.aicloud.translate.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class FileUtil {
public static String loadMediaAsBase64(String path) throws IOException {
FileInputStream fileInputStream = new FileInputStream(path);
byte[] temp = new byte[1024 * 1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int l = 0;
while ((l = fileInputStream.read(temp)) != -1) {
bos.write(temp, 0, l);
}
fileInputStream.close();
bos.close();
return Base64.getEncoder().encodeToString(bos.toByteArray());
}
public static String saveFile(String path, byte[] data, boolean needDecode) throws IOException {
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
byte[] bytes = data;
if (needDecode) {
String base64 = new String(data, StandardCharsets.UTF_8);
bytes = Base64.getDecoder().decode(base64);
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(bytes);
fileOutputStream.close();
return path;
}
}
HttpUtil.java
package com.youdao.aicloud.translate.utils;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
public class HttpUtil {
private static OkHttpClient httpClient = new OkHttpClient.Builder().build();
public static byte[] doGet(String url, Map<String, String[]> header, Map<String, String[]> params, String expectContentType) {
Request.Builder builder = new Request.Builder();
addHeader(builder, header);
addUrlParam(builder, url, params);
return requestExec(builder.build(), expectContentType);
}
public static byte[] doPost(String url, Map<String, String[]> header, Map<String, String[]> body, String expectContentType) {
Request.Builder builder = new Request.Builder().url(url);
addHeader(builder, header);
addBodyParam(builder, body, "POST");
return requestExec(builder.build(), expectContentType);
}
private static void addHeader(Request.Builder builder, Map<String, String[]> header) {
if (header == null) {
return;
}
for (String key : header.keySet()) {
String[] values = header.get(key);
if (values != null) {
for (String value : values) {
builder.addHeader(key, value);
}
}
}
}
private static void addUrlParam(Request.Builder builder, String url, Map<String, String[]> params) {
if (params == null) {
return;
}
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
for (String key : params.keySet()) {
String[] values = params.get(key);
if (values != null) {
for (String value : values) {
urlBuilder.addQueryParameter(key, value);
}
}
}
builder.url(urlBuilder.build());
}
private static void addBodyParam(Request.Builder builder, Map<String, String[]> body, String method) {
if (body == null) {
return;
}
FormBody.Builder formBodyBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
for (String key : body.keySet()) {
String[] values = body.get(key);
if (values != null) {
for (String value : values) {
formBodyBuilder.add(key, value);
}
}
}
builder.method(method, formBodyBuilder.build());
}
private static byte[] requestExec(Request request, String expectContentType) {
Objects.requireNonNull(request, "okHttp request is null");
try (Response response = httpClient.newCall(request).execute()) {
if (response.code() == 200) {
ResponseBody body = response.body();
if (body != null) {
String contentType = response.header("Content-Type");
if (contentType != null && !contentType.contains(expectContentType)) {
String res = new String(body.bytes(), StandardCharsets.UTF_8);
System.out.println(res);
return null;
}
return body.bytes();
}
System.out.println("response body is null");
} else {
System.out.println("request failed, http code: " + response.code());
}
} catch (IOException ioException) {
System.out.println("request exec error: " + ioException.getMessage());
}
return null;
}
}
WebSocketUtil.java
package com.youdao.aicloud.translate.utils;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
public class WebSocketUtil extends WebSocketListener {
private static WebSocket webSocket = null;
private static FileOutputStream savePathStream = null;
/**
* 初始化websocket连接
*
* @param url paas接口地址
*/
public static void initConnection(String url) {
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url(url).build();
webSocket = client.newWebSocket(request, new WebSocketUtil());
}
public static void initConnection(String url, Map<String, String[]> params) {
StringBuilder paramsBuilder = new StringBuilder();
for (Map.Entry<String, String[]> entry : params.entrySet()) {
String key = entry.getKey();
String[] values = entry.getValue();
for (String value : values) {
paramsBuilder.append(key).append("=").append(value).append("&");
}
}
paramsBuilder.deleteCharAt(paramsBuilder.length() - 1);
initConnection(url + "?" + paramsBuilder);
}
/**
* 配置接收binary message的文件路径
*
* @param path 文件路径
*/
public static void binaryMessageConfig(String path) {
File file = new File(path);
try {
savePathStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
* 发送text message
*
* @param textMsg text message
*/
public static void sendTextMessage(String textMsg) {
if (webSocket == null) {
throw new RuntimeException("websocket connection not established");
}
webSocket.send(textMsg);
System.out.println("send text message: " + textMsg);
}
/**
* 发送binary message
*
* @param binaryMsg binary message
*/
public static void sendBinaryMessage(ByteString binaryMsg) {
if (webSocket == null) {
throw new RuntimeException("websocket connection not established");
}
webSocket.send(binaryMsg);
System.out.println("send binary message length: " + binaryMsg.size());
}
@Override
public void onOpen(WebSocket webSocket, Response response) {
System.out.println("connection open");
}
@Override
public void onMessage(WebSocket webSocket, String text) {
System.out.println("received text message: " + text);
// 该判断方式仅用作demo展示, 生产环境请使用json解析
if (!text.contains(""errorCode":"0"")) {
System.exit(0);
}
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
System.out.println("received text message length: " + bytes.size());
if (savePathStream != null) {
try {
savePathStream.write(bytes.toByteArray());
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
System.out.println("connection closed, code: " + code + ", reason: " + reason);
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
System.out.println("connection failed.");
t.printStackTrace();
}
}
POM.XML
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.9</version>
</dependency>
测试案例
TranslateDemo.java
package com.youdao.aicloud.translate;
import com.youdao.aicloud.translate.utils.AuthV3Util;
import com.youdao.aicloud.translate.utils.HttpUtil;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
/**
* 网易有道智云翻译服务api调用demo
* api接口: https://openapi.youdao.com/api
*/
public class TranslateDemo {
private static final String APP_KEY = ""; // 应用ID
private static final String APP_SECRET = ""; // 应用密钥
public static void main(String[] args) throws NoSuchAlgorithmException {
// 添加请求参数
Map<String, String[]> params = createRequestParams();
// 添加鉴权相关参数
AuthV3Util.addAuthParams(APP_KEY, APP_SECRET, params);
// 请求api服务
byte[] result = HttpUtil.doPost("https://openapi.youdao.com/api", null, params, "application/json");
// 打印返回结果
if (result != null) {
System.out.println(new String(result, StandardCharsets.UTF_8));
}
// byte[]转json
// JSONObject jsonObject = JSON.parseObject(new String(result, StandardCharsets.UTF_8));
System.exit(1);
}
private static Map<String, String[]> createRequestParams() {
/*
* note: 将下列变量替换为需要请求的参数
* 取值参考文档: https://ai.youdao.com/DOCSIRMA/html/%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E7%BF%BB%E8%AF%91/API%E6%96%87%E6%A1%A3/%E6%96%87%E6%9C%AC%E7%BF%BB%E8%AF%91%E6%9C%8D%E5%8A%A1/%E6%96%87%E6%9C%AC%E7%BF%BB%E8%AF%91%E6%9C%8D%E5%8A%A1-API%E6%96%87%E6%A1%A3.html
*/
String q = "待翻译文本";
String from = "源语言语种";
String to = "目标语言语种";
return new HashMap<String, String[]>() {{
put("q", new String[]{q});
put("from", new String[]{from});
put("to", new String[]{to});
}};
}
}