xf 翻译
This commit is contained in:
33
src/main/java/com/newyetai/ai/controller/AiController.java
Normal file
33
src/main/java/com/newyetai/ai/controller/AiController.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.newyetai.ai.controller;
|
||||
|
||||
import com.newyetai.common.AlitaResult;
|
||||
import com.newyetai.sdk.xf.model.ChatReq;
|
||||
import com.newyetai.sdk.xf.model.TranslateReq;
|
||||
import com.newyetai.sdk.xf.util.XfUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Api(tags = "ai")
|
||||
@RestController
|
||||
@RequestMapping("/ai")
|
||||
public class AiController {
|
||||
|
||||
@PostMapping("chat")
|
||||
@ApiOperation("ai对话")
|
||||
public AlitaResult<String> chat(@Validated @RequestBody ChatReq req) {
|
||||
return AlitaResult.success(XfUtils.chat(req));
|
||||
}
|
||||
|
||||
@PostMapping("translate")
|
||||
@ApiOperation("ai翻译")
|
||||
public AlitaResult<String> chat(@Validated @RequestBody TranslateReq req) {
|
||||
return AlitaResult.success(XfUtils.translate(req));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -34,5 +34,8 @@ public class XfProperties implements Serializable{
|
||||
private String iatHostUrl;
|
||||
/** 语音合成地址 **/
|
||||
private String ttsHostUrl;
|
||||
/** 机器翻译niutrans **/
|
||||
private String otsHostUrl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.newyetai.sdk.xf.model;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -19,6 +20,7 @@ public class ChatReq implements Serializable{
|
||||
@Default
|
||||
private String model = "4.0Ultra";
|
||||
@Singular
|
||||
@NotNull(message = "消息内容不能为空")
|
||||
private List<MessageDTO> messages;
|
||||
|
||||
|
||||
|
||||
67
src/main/java/com/newyetai/sdk/xf/model/TranslateReq.java
Normal file
67
src/main/java/com/newyetai/sdk/xf/model/TranslateReq.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package com.newyetai.sdk.xf.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.newyetai.sdk.common.dto.ISdkRequest;
|
||||
import com.newyetai.sdk.xf.model.TranslateReq.TranslateRes;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Builder.Default;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class TranslateReq implements ISdkRequest<XfRes<TranslateRes>> {
|
||||
|
||||
private static ParameterizedTypeReference<XfRes<TranslateRes>> type = new ParameterizedTypeReference<XfRes<TranslateRes>>() {
|
||||
};
|
||||
/** 中文 */
|
||||
private static final String CN = "cn";
|
||||
/** 维语 */
|
||||
private static final String UY = "uy";
|
||||
|
||||
@NotBlank(message = "待翻译文本不能为空")
|
||||
private String text;
|
||||
@Default
|
||||
private String from = CN;
|
||||
@Default
|
||||
private String to = UY;
|
||||
|
||||
@Override
|
||||
public ParameterizedTypeReference getResponseType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static class TranslateRes {
|
||||
private TranslateResDTO result;
|
||||
}
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static class TranslateResDTO {
|
||||
private String from;
|
||||
private String to;
|
||||
@JsonProperty("trans_result")
|
||||
private TranslateResultDTO transResult;
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static class TranslateResultDTO {
|
||||
private String src;
|
||||
private String dst;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
19
src/main/java/com/newyetai/sdk/xf/model/XfRes.java
Normal file
19
src/main/java/com/newyetai/sdk/xf/model/XfRes.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.newyetai.sdk.xf.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class XfRes<T> {
|
||||
|
||||
private Integer code;
|
||||
private String message;
|
||||
private String sid;
|
||||
private T data;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,24 @@
|
||||
package com.newyetai.sdk.xf.service;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.newyetai.common.constant.CommonConstants;
|
||||
import com.newyetai.sdk.xf.model.TranslateReq;
|
||||
import com.newyetai.sdk.xf.model.TranslateReq.TranslateRes;
|
||||
import com.newyetai.sdk.xf.model.XfRes;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -67,6 +86,149 @@ public class XfSparkProvider {
|
||||
public static String dealJson(String content) {
|
||||
return content.replaceAll("(```json\n)|(\n```)|(\n)", "");
|
||||
}
|
||||
|
||||
public static AlitaResult<String> translate(TranslateReq translateReq){
|
||||
return translate(translateReq, xfProperties);
|
||||
}
|
||||
|
||||
public static AlitaResult<String> translate(TranslateReq translateReq, XfProperties xfProperties){
|
||||
|
||||
ResponseEntity<XfRes<TranslateRes>> response = null;
|
||||
try {
|
||||
try {
|
||||
String body = buildHttpBody(translateReq, xfProperties);
|
||||
|
||||
HttpHeaders header = buildHttpHeader(body, xfProperties);
|
||||
// 发送请求
|
||||
HttpEntity requestEntity = new HttpEntity(body, header);
|
||||
response =
|
||||
HttpUtils.restTemplate.exchange(xfProperties.getOtsHostUrl(),
|
||||
HttpMethod.POST, requestEntity, translateReq.getResponseType());
|
||||
} catch (Exception e) {
|
||||
log.error("xfSpark http error:{}", e.getMessage());
|
||||
return AlitaResult.error(SdkConstants.SDK_HTTP_INVOKE_ERROR_CODE, e.getMessage());
|
||||
}
|
||||
try {
|
||||
XfRes<TranslateRes> res = response.getBody();
|
||||
if (!res.getCode().equals(0)) {
|
||||
return AlitaResult.error(SdkConstants.SDK_HTTP_INVOKE_RESPONSE_FAIL_CODE,
|
||||
res.getCode() + CommonConstants.COLON + res.getMessage());
|
||||
}
|
||||
return AlitaResult.success(res.getData().getResult().getTransResult().getDst());
|
||||
} catch (Exception e) {
|
||||
return AlitaResult.error(SdkConstants.SDK_RESPONSE_CONVERT_ERROR_CODE, "xf返回结果获取content失败");
|
||||
}
|
||||
|
||||
} finally {
|
||||
log.info("xfSpark invoke:{}",
|
||||
JsonUtils
|
||||
.toJsonString(
|
||||
DefaultSdkInvokeLogDTO.builder().requestData(translateReq).responseData(response)
|
||||
.build()));
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 组装http请求头
|
||||
*/
|
||||
public static HttpHeaders buildHttpHeader(String body, XfProperties xfProperties)
|
||||
throws MalformedURLException, NoSuchAlgorithmException, InvalidKeyException {
|
||||
HttpHeaders header = new HttpHeaders();
|
||||
URL url = new URL(xfProperties.getOtsHostUrl());
|
||||
|
||||
//时间戳
|
||||
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
Date dateD = new Date();
|
||||
String date = format.format(dateD);
|
||||
//System.out.println("【OTS WebAPI date】\n" + date);
|
||||
|
||||
//对body进行sha256签名,生成digest头部,POST请求必须对body验证
|
||||
String digestBase64 = "SHA-256=" + signBody(body);
|
||||
//System.out.println("【OTS WebAPI digestBase64】\n" + digestBase64);
|
||||
|
||||
//hmacsha256加密原始字符串
|
||||
StringBuilder builder = new StringBuilder("host: ").append(url.getHost()).append("\n").//
|
||||
append("date: ").append(date).append("\n").//
|
||||
append("POST ").append(url.getPath()).append(" HTTP/1.1").append("\n").//
|
||||
append("digest: ").append(digestBase64);
|
||||
//System.out.println("【OTS WebAPI builder】\n" + builder);
|
||||
String sha = hmacsign(builder.toString(), xfProperties.getApiSecret());
|
||||
//System.out.println("【OTS WebAPI sha】\n" + sha);
|
||||
|
||||
//组装authorization
|
||||
String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", xfProperties.getApiKey(), "hmac-sha256", "host date request-line digest", sha);
|
||||
//System.out.println("【OTS WebAPI authorization】\n" + authorization);
|
||||
|
||||
header.add("Authorization", authorization);
|
||||
header.add("Content-Type", "application/json");
|
||||
header.add("Accept", "application/json,version=1.0");
|
||||
header.add("Host", url.getHost());
|
||||
header.add("Date", date);
|
||||
header.add("Digest", digestBase64);
|
||||
//System.out.println("【OTS WebAPI header】\n" + header);
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 组装http请求体
|
||||
*/
|
||||
public static String buildHttpBody(TranslateReq translateReq, XfProperties xfProperties)
|
||||
throws UnsupportedEncodingException {
|
||||
JsonObject body = new JsonObject();
|
||||
JsonObject business = new JsonObject();
|
||||
JsonObject common = new JsonObject();
|
||||
JsonObject data = new JsonObject();
|
||||
//填充common
|
||||
common.addProperty("app_id", xfProperties.getAppId());
|
||||
//填充business
|
||||
business.addProperty("from", translateReq.getFrom());
|
||||
business.addProperty("to", translateReq.getTo());
|
||||
//填充data
|
||||
//System.out.println("【OTS WebAPI TEXT字个数:】\n" + TEXT.length());
|
||||
byte[] textByte = translateReq.getText().getBytes("UTF-8");
|
||||
String textBase64 = new String(Base64.getEncoder().encodeToString(textByte));
|
||||
//System.out.println("【OTS WebAPI textBase64编码后长度:】\n" + textBase64.length());
|
||||
data.addProperty("text", textBase64);
|
||||
//填充body
|
||||
body.add("common", common);
|
||||
body.add("business", business);
|
||||
body.add("data", data);
|
||||
return body.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对body进行SHA-256加密
|
||||
*/
|
||||
private static String signBody(String body) {
|
||||
MessageDigest messageDigest;
|
||||
String encodestr = "";
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("SHA-256");
|
||||
messageDigest.update(body.getBytes("UTF-8"));
|
||||
encodestr = Base64.getEncoder().encodeToString(messageDigest.digest());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return encodestr;
|
||||
}
|
||||
|
||||
/**
|
||||
* hmacsha256加密
|
||||
*/
|
||||
private static String hmacsign(String signature, String apiSecret)
|
||||
throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Charset charset = Charset.forName("UTF-8");
|
||||
Mac mac = Mac.getInstance("hmacsha256");
|
||||
SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(charset), "hmacsha256");
|
||||
mac.init(spec);
|
||||
byte[] hexDigits = mac.doFinal(signature.getBytes(charset));
|
||||
return Base64.getEncoder().encodeToString(hexDigits);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.newyetai.sdk.xf.util;
|
||||
|
||||
import com.newyetai.sdk.xf.model.TranslateReq;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -229,4 +230,16 @@ public class XfUtils {
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
public static String chat(ChatReq req) {
|
||||
AlitaResult<String> result = XfSparkProvider.httpChat(req);
|
||||
Assert.isTrue(result.getSuccess(), result.getMsg());
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
public static String translate(TranslateReq req) {
|
||||
AlitaResult<String> result = XfSparkProvider.translate(req);
|
||||
Assert.isTrue(result.getSuccess(), result.getMsg());
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user