У меня есть служебный класс TestCracker. У него есть метод testInput
который принимает текст, отправляет запрос службе перевода с этим текстом в качестве параметра и возвращает ответ JSON String:
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
я попытался отобразить ответ 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
ответа отображается правильно (первое слово), 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
, так что вы можете видеть результат для этого с соответствующим символом.
Первый подход лучше, так как он решит проблемы для всего приложения.
java.net.URLEncoder.encode(text)
? Я считаю, что это более уместно, даже если это работает при запуске изнутри IDE.