有道翻译返回的结果是 json,为了处理json,需要引入 jackson(当然,如果你喜欢别的json工具也可以,参考本篇,将你用的json 工具类处理一下即可)
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dev.guu</groupId>
<artifactId>fx-translate-box</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
dev.guu.fx.translate.box.AppStarter
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
json 处理工具类
package dev.guu.kit.string;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.SneakyThrows;
/**
* @author guweichao json相关工具集
* @since
* 2019年6月28日
*/
public class JsonKit {
private final static String lineSeparator = System.lineSeparator();
private final static ThreadLocal<ObjectMapper> mapper = ThreadLocal
.withInitial(() -> JsonMapper.builder().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS).build()
.setSerializationInclusion(Include.NON_EMPTY));
@SneakyThrows
public static String toJson(Object obj) {
return mapper.get().writeValueAsString(obj);
}
@SneakyThrows
public static String toJsonFormat(Object obj) {
return mapper.get().writerWithDefaultPrettyPrinter().writeValueAsString(obj);
}
@SneakyThrows
public static <T> T toBean(String json, Class<T> clz) {
return mapper.get().readValue(json, clz);
}
}
AppStarter
package dev.guu.fx.translate.box;
import javafx.application.Application;
public class AppStarter {
public static void main(String[] args) {
Application.launch(BoxMain.class,args);
}
}
MainBox
package dev.guu.fx.translate.box;
import dev.guu.fx.translate.box.youdao.YoudaoV3;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class BoxMain extends Application {
private Stage primaryStage;
private TextArea inputTextArea;
@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
Pane root = new VBox();
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("翻译工具箱");
primaryStage.setScene(scene);
primaryStage.show();
createInputTextArea(root);
createOutput(root);
}
private void createInputTextArea(Pane root) {
inputTextArea = new TextArea();
inputTextArea.setPromptText("请输入要翻译的文本...");
inputTextArea.setPrefHeight(200);
VBox box = new VBox(inputTextArea);
root.getChildren().add(box);
primaryStage.widthProperty().addListener((obs, oldV, newV) -> inputTextArea.setPrefWidth(newV.doubleValue()));
}
private void createOutput(Pane root) {
HBox box = new HBox();
root.getChildren().add(box);
createYoudao(box);
}
private void createYoudao(HBox parent) {
Label label = new Label("有道翻译:");
Button btn = new Button("翻译");
label.setFont(Font.font("微软雅黑", 24));
TextArea output = new TextArea();
output.setPromptText("等待输入...");
output.setEditable(false);
output.setFont(Font.font("宋体", 20));
parent.getChildren().add(new VBox(label,btn, output));
btn.setOnMouseClicked(e -> {
String text = inputTextArea.getText();
if (isBlank(text)) {
output.setText("请输入");
} else {
output.setText("翻译中...");
// fx的多线程 ,
Platform.runLater(() -> {
String trans = YoudaoV3.translate(text);
output.setText(trans);
});
}
});
}
boolean isBlank(String s) {
return s == null || s.isBlank();
}
}
有道翻译结果 json 处理需要的文件
package dev.guu.fx.translate.box.youdao;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true)
public class YoudaoRoot {
private List<String> translation;
private List<YoudaoKeyValue> web;
}
package dev.guu.fx.translate.box.youdao;
import lombok.Data;
import java.util.List;
@Data
public class YoudaoKeyValue {
private String key;
private List<String> value;
}
有道翻译工具类(注意,个人API id和secret为私人信息,你需要自行申请)
有道智云控制台 (youdao.com) ai.youdao.com/console/#/
package dev.guu.fx.translate.box.youdao;
import dev.guu.kit.string.JsonKit;
import dev.guu.kit.string.StringKit;
import lombok.SneakyThrows;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
public class YoudaoV3 {
private static final String APP_KEY = "替换成你的appId";
private static final String APP_SECRET = "替换为你的 appSecret";
private static final String YOUDAO_URL = "https://openapi.youdao.com/api?";
public static String translate(String text) {
Map<String, String> params = new HashMap<>();
long ms = System.currentTimeMillis();
String salt = String.valueOf(ms);
params.put("from", "auto");
params.put("to", StringKit.isEn(text) ? "zh-CHS":"en");
params.put("signType", "v3");
String curtime = String.valueOf(ms / 1000);
params.put("curtime", curtime);
String signStr = APP_KEY + truncate(text) + salt + curtime + APP_SECRET;
String sign = getDigest(signStr);
params.put("appKey", APP_KEY);
params.put("q", text);
params.put("salt", salt);
params.put("sign", sign);
// params.put("vocabId", "您的用户词表ID");
/** 处理结果 */
return requestForHttp(YOUDAO_URL, params);
}
@SneakyThrows
public static String requestForHttp(String url, Map<String, String> params) {
StringJoiner sj = new StringJoiner("&");
params.forEach((k, v) -> sj.add(k + "=" + StringKit.encode(v)));
url += sj.toString();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString("a"))
.setHeader("Content-type", "application/json; charset=UTF-8")
.uri(URI.create(url)).build();
HttpResponse<String> send = client.send(request, HttpResponse.BodyHandlers.ofString());
String body = send.body();
System.out.println(body);
YoudaoRoot root = JsonKit.toBean(body, YoudaoRoot.class);
System.out.println(root);
return JsonKit.toJsonFormat(root);
}
/**
* 生成加密字段
*/
static String getDigest(String string) {
if (string == null) {
return null;
}
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
byte[] btInput = string.getBytes(StandardCharsets.UTF_8);
try {
MessageDigest mdInst = MessageDigest.getInstance("SHA-256");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (byte byte0 : md) {
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
public static String truncate(String q) {
if (q == null) {
return null;
}
int len = q.length();
return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len));
}
}