Ответы (8)
ins0mnia | 17.04.2009, 17:32 #
Добрый день, всезнающий all
У меня возник stupid blocking point при реализации моего веб-приложения с использованием Postgresql 8.3 (running on Windows).
Кратко о приложении: чистая JSP&Servlet платформа (даже без базовых taglibs), деплоится на JBoss AS 4.2.2.GA и использует Win PostgreSQL 8.3.
Проблема заключается в сохранении в базе данных записей, поступивших из JSP (все JSP pages используют
Java
1
charset=UTF-8" and pageEncoding="UTF-8", в некорректной кодировке (некорректность определена визуально - при просмотре записей чере pgAdmin III, а также при дальнейшей их выборке из БД и передаче через HttpSession для отображения их в тех же JSP страницах.
Скрипты создания БД и таблицы:
Database 'test'
Java
1
2
3
CREATE DATABASE test WITH OWNER = dwh ENCODING = 'UTF8';Table 'users'
Java
1
2
3
4
5
6
7
8
9
CREATE TABLE events( id serial NOT NULL, field1 text NOT NULL, field2 text NOT NULL, CONSTRAINT events_pk PRIMARY KEY (id))WITH (OIDS=FALSE);ALTER TABLE events OWNER TO dev;Страница JSP requestsList.jsp (часть кода):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<% String flowControl = (String)session.getAttribute("flowControl");%>
<table cellspacing="0" cellspacing="5" width="150" border="0"> <tr> <td bgcolor="F6F6F6"> <font face="Verdana">Поиск</font> <form> <input type="hidden" name="action" value="search"> <input type="text" name="keyword" size="10"> <input type="submit" value="Искать"> </form>После ввода в поле значени "тест" и нажатия кнопки "Создать" действие передаётся по следующей ссылку
Вот код обработки в сервлете:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {...if(request.getParameter("action").equals("search")) { session = request.getSession(); boolean created = dbHelper.createEvent(request.getParameter("keyword"), session); if(created) session.setAttribute("message", "New event created successfully."); else session.setAttribute("message", "New event creation failed."); session.setAttribute("action", request.getParameter("action"));
RequestDispatcher rd = getServletContext().getRequestDispatcher("/WEB-INF/requestsList.jsp"); rd.forward(request, response); }...Код dbHelper.createEvent(String value):
Вот собственно говоря все детали.
Сервер - Windows 2003 Server, Location=Ukraine, lang for the non-Unicode program (Advanced tab in Regional Settings)=Ukrainian (все чекбоксы включены).
При просмотре через pgAdmin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
14;"òåñò";"òåñò";1public boolean createEvent(String keyword, HttpSession session){ boolean result = false; Connection conn = this.getConnection(); try { Statement createStatement = conn.createStatement(); String test = new String(keyword.getBytes("UTF-8"), "UTF-8"); // также были попытки не трансформить строку System.out.println(test); PreparedStatement prep = conn.prepareStatement("insert into events(field1, field2) values(?, ?)"); prep.setString(1, keyword); prep.setString(2, keyword); int affect = prep.executeUpdate(); if(affect == 1) result = true; } catch (SQLException sqle) { sqle.printStackTrace(); } catch (UnsupportedEncodingException ioe) { ioe.printStackTrace(); } return result;}На JSP выводит: òåñò
Интересно то, что если я ввожу на другой JSP в поле ввода "тест", а затем ищу это значение в таблице - возвращается одна запись.
Большая просьба ткнуть носом в тот момент, где скрывается ошибка.
Заранее благодарен
NeoNYura | 17.04.2009, 17:39 #
Вы бы распечатали, вашу информацию во всех точках, для того что бы понять где происходит проблема с кодировкой.\
Если в Сервлете то можно добавить следующий код
Java
1
2
3
4
5
try {
request.setCharacterEncoding("utf8");} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();}1
System.out.println(test);если текст правильный, то база таки у вас не в утф-8 (хотя создается база вроде правильно)
Добавлено позднее:
это излишество
Java
1
String test = new String(keyword.getBytes("UTF-8"), "UTF-8");
Добавлено позднее:
так не пробвали писать?
Xml
1
<%@ page contentType="text/html; charset=utf-8"%>1
2
3
4
5
6
7
8
9
10
11
12
13
14
try {
Statement createStatement = conn.createStatement(); //String test = new String(keyword.getBytes("UTF-8"), "UTF-8"); System.out.println(keyword); PreparedStatement prep = conn.prepareStatement("insert into events(field1, field2) values(?, ?)"); prep.setString(1, keyword); prep.setString(2, keyword); int affect = prep.executeUpdate();
if(affect == 1) result = true; } catch (SQLException sqle) {
sqle.printStackTrace(); }Вот результат
Java
1
2
3
4
System.out.println(keyword);
18:01:56,858 INFO [STDOUT] ?????? ?????? ??????
Также в начале doGet и doPost поставил:
Java
1
request.setCharacterEncoding("utf-8");...не помогло
Asal | 20.04.2009, 17:51 #
еще можно попробывать поставить в настройках соединения UTF-8 для результата и данных которые вставляются
ins0mnia | 21.04.2009, 11:52 #
Есть некий прогресс: явно указал метод post для формы и action (на контроллер действий) - в логах jboss и таблице postgresql данные пошли русскими, корректными символами
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<% String flowControl = (String)session.getAttribute("flowControl");%><table cellspacing="0" cellspacing="5" width="150" border="0">
<tr> <td bgcolor="F6F6F6"> <font face="Verdana">Поиск</font> <form method="post" action="/ssweb/Controller">
<input type="hidden" name="action" value="search">
<input type="text" name="keyword" size="10">
<input type="submit" value="Искать">
</form>Также установил, что при отсутствии
Java
1
request.setCharacterEncoding("utf-8");символы в jboss log & postgre table будут в некорректной кодировке.
В принципе это решение удовлетворяет текущим потребностям, но на будущее хотелось бы разъяснить для себя эту тему.
Взглянув на значение keyword в этой uri
Java
1
http://serv_ip:8081/ssweb/Controller?action=search&keyword=%F2%E5%F1%F2, я подумал, что при [code=java]request.getParameter("keyword") в программу данные попадают вот в такой вот, неприемлемой, кодировке.
Есть мнение использовать атрибут Connector'a URIEncoding (server.xml JBoss'овского Tomcat'а)
This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.
и возможно это позволит решить трабл с обработкой в doGet().
ins0mnia | 21.04.2009, 12:38 #
Прошу простить за общение с самим собой:)
С doGet решилась проблема использованием того самого атрибута URIEncoding. Теперь мой Connector выглядит так:
Java
1
2
3
4
5
<Connector port="8081" address="${jboss.bind.address}"
maxThreads="250" maxHttpHeaderSize="8192"
emptySessionPath="true" protocol="HTTP/1.1"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8"/>
URL, в свою очередь, получается таким:
Java
1
http://serv_ip:8081/ssweb/Controller?action=search&keyword=тестСобственно сабж, мне кажется, можно считать разобранным
ins0mnia | 27.04.2009, 09:08 #
considered as solved