java - Java Servlet 翻译 API 请求编码问题:德语字符
问题描述
我有一个实用程序类 TestCracker。它有一个testInput
接收文本的方法,向翻译服务发送请求,该文本作为参数,并返回响应 JSON 字符串:
public class TestCracker {
private String ACCESS_TOKEN = "XXXXXXXXXX";
public static void main(String[] args) {
System.out.println(new TestCracker().testInput("Lärm"));
}
public String testInput(String text) {
String translateLink = "https://translate.yandex.net/api/v1.5/tr.json/translate" +
"?key=" + ACCESS_TOKEN + "&text=" + text +
"&lang=de-en" + "&format=plain" + "&options=1";
try {
URL translateURL = new URL(translateLink);
HttpURLConnection connection = (HttpURLConnection) translateURL.openConnection();
setupGETConnection(connection);
connection.connect();
InputStream input = connection.getInputStream();
String inputString = new Scanner(input, "UTF-8").useDelimiter("\\Z").next();
JSONObject jsonObject = new JSONObject(inputString);
return text + "; " + inputString;
}
catch (Exception e) {
System.out.println("Couldn't connect " + e);
return "None";
}
}
private void setupGETConnection(HttpURLConnection connection) throws Exception {
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
}
}
在方法main
中,我尝试显示 string 的响应 JSON Lärm
。它工作正常:
Lärm; {"code":200,"detected":{"lang":"de"},"lang":"de-en","text":["Noise"]}
但是,当我尝试使用 Servlet 和浏览器而不是 IDE 来运行和显示相同的内容时:
public class TestServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String resultPath;
request.setCharacterEncoding("UTF-8");
response.getWriter().print(request.getParameter("input-text2"));
response.getWriter().println(new TestCracker().testInput(request.getParameter("input-text2")));
}
}
运行时,TestServlet
输出:
LärmLärm; {"code":200,"detected":{"lang":"en"},"lang":"de-en","text":["L?rm"]}
可以看出,这个词Lärm
是从一个表格中得到的——响应字符串中的第一个词显示正确(第一个词),testInput
得到了正确的词(第二个词),但是翻译服务的响应是错误的(之后的部分;
): 服务无法翻译并返回初始单词的损坏版本: L?rm
.
我不明白为什么会这样。如果将正确的词传递给方法,错误会发生在哪里?如果在 IDE 中运行的方法返回正确的翻译(“噪音”)?
解决方案
如果您使用的是 Tomcat,则URIEncoding
必须正确设置。如果参数在 URL (GET) 上。这必须在定义连接器的 server.xml 中完成。
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector URIEncoding="UTF-8" port="8080"/>
<Engine defaultHost="localhost" name="Catalina">
<Host appBase="webapps" name="localhost"/>
</Engine>
</Service>
</Server>
或者,如果您不想玩弄服务器设置,请阅读编码支持。
喜欢
response.getWriter()
.println(new TestCracker()
.testInput(
new String(request.getParameter("input-text2").getBytes(),"UTF-8"))
);
具有response.getWriter().print()
默认utf-8
打印功能,因此您可以看到具有正确字符的输出。
第一种方法更好,因为它将解决整个应用程序的问题。
推荐阅读
- arduino - 如何在 IF 语句中使用串行数据在 Arduino Due 上做某事
- javascript - React Context:嵌套重用/增强(反模式?)
- php - Laravel 多个计数,条件来自一张表
- python - 使用ffpyplayer时编译python代码时出错
- asp.net-core - 使用 openapi 3.0.1 和 .Net Core 3.1 和 Swashbucle.AspNetCore.SwaggerGen 为 swagger.json 中的数组查询参数生成explode: false
- angular - 组件上传后如何使自定义验证器工作?
- database - Keycloak - 基于经过身份验证的用户显示资源的最佳方式
- reactjs - redux-persist 无法创建同步存储。失败回到 noop 存储。这是什么意思?
- alexa - Alexa的替代声音
- routes - Vaadin 流重定向到页面重新加载时的特定路由