Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Косяки с кодировкой при CLOB через сервлет. / 18 сообщений из 18, страница 1 из 1
21.09.2007, 17:41:09
    #34818670
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Суть проблемы - в базе лежит xml файл в виде CLOB. Его нужно вывести. Вывести то получается, но возникают проблемы с кодировкой. Файл непонятным мне образом в непонятном мне месте переrодируется, хотя в базе он лежит в абсолютно нормальном виде. Посдскажите, в каком месте он перекодируется и как это исправить. Заранее спасибо.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
 import  java.io.*;
 import  javax.servlet.*;
 import  javax.servlet.http.*;
 import  java.sql.*;
 import  java.util.Properties;
 import  oracle.jdbc.driver.OracleDriver;

 public   class  UnloadCLOB  extends  HttpServlet
{
     
      public   void  service (HttpServletRequest request, HttpServletResponse response)
      throws  ServletException, IOException
	 {
         String line;
	     response.setContentType("text/xml; charset=Windows-1251");
	     response.addHeader("Content-Disposition", "attachment; filename=Policy.xml");
           
                Connection conn =  null ;
		 ResultSet resultSet =  null ;
		 Statement statement =  null ; 
		  try  {
		    	
	      Class .forName("oracle.jdbc.driver.OracleDriver");
	     String query = "select * from clob_test where id=3";
     	     conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:sid","user", "password");
	     statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
	     resultSet = statement.executeQuery(query);
                resultSet.first();
                Clob clob = resultSet.getClob( 1 );	
                Reader in = clob.getCharacterStream();
	     PrintWriter out = response.getWriter();
                BufferedReader br =  new  BufferedReader(in); 
	     out.println( out.getCharacterEncoding())
			     do 
                  { 
                    line = br.readLine();
	           	    out.println(line);
			      }
                while  (line !=  null ); 
             	 }
		  catch  (ClassNotFoundException e)
		     {
			    e.printStackTrace();
		     } 
		  catch  (SQLException e) 
			 {
			    e.printStackTrace();
		     }	       
  
	 }
...
Рейтинг: 0 / 0
21.09.2007, 17:57:08
    #34818706
unicornmirage
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
какая кодировка используется в БД?
и какая кодировка по-умолчанию используется в JVM? (посмотреть параметр System.getProperty("file.encoding"))
...
Рейтинг: 0 / 0
21.09.2007, 18:13:58
    #34818764
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
В базе данных, да и в файле установлена кодировка Windows-1251. Насчет System.getProperty("file.encoding") щас выясню. Но рантше вывод кириллицы проблем не вызывал. А как обратился к CLOB - проблемы.
...
Рейтинг: 0 / 0
21.09.2007, 18:17:50
    #34818780
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
System.getProperty("file.encoding") вернуло Cp1251
...
Рейтинг: 0 / 0
21.09.2007, 18:33:18
    #34818823
unicornmirage
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
а есть попробовать вот так?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
...
Properties properties= new  Properties();
properties.setProperty("user","user");
properties.setProperty("password","password");
//properties.setProperty("useUnicode","true");
properties.setProperty("characterEncoding","windows-1251");
Connection connection=DriverManager.getConnection("jdbc:oracle:thin:@host:1521:sid", properties);

...
...
Рейтинг: 0 / 0
21.09.2007, 18:34:27
    #34818829
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Ashitkin.Alex
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
                Clob clob = resultSet.getClob( 1 );	
                Reader in = clob.getCharacterStream();
	     PrintWriter out = response.getWriter();
                BufferedReader br =  new  BufferedReader(in); 
	     out.println( out.getCharacterEncoding())
			     do 
                  { 
                    line = br.readLine();
	           	    out.println(line);
			      }
                while  (line !=  null ); 
...  

Попробуй просто:
Код: plaintext
out.println(clob.getSubString( 1 , ( int )clob.length()));
...
Рейтинг: 0 / 0
21.09.2007, 18:38:39
    #34818838
unicornmirage
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Если данные небольшие, то можно просто вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
ResultSet rs = ...;
//Clob c = rs.getClob(1);  //не используем клоб
 byte [] data = rs.getBytes();  //вернет данные как есть

//а затем что угодно с ними делать:
String xml =  new  String(data);
//и т.п.
...
Рейтинг: 0 / 0
21.09.2007, 18:39:25
    #34818839
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
щас попробую через стринг. а Ограничений нет на длину String а Java? а то у меня clob большой. Или имелось ввиду кусочками считывать через SubString?
...
Рейтинг: 0 / 0
21.09.2007, 18:46:59
    #34818855
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Ashitkin.Alexщас попробую через стринг. а Ограничений нет на длину String а Java? а то у меня clob большой. Или имелось ввиду кусочками считывать через SubString?
У CLOB.substring() второй параметр имеет тип int , максимальное значение которого равно Integer. MAX_VALUE, т.е. 2 31 -1. Конечно, меньше чем Long.MAX_VALUE=2 63 -1, возвращаемый CLOB.length(), но м.б. и его хватит?;)
...
Рейтинг: 0 / 0
21.09.2007, 18:50:31
    #34818868
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Код: plaintext
1.
2.
3.
4.
5.
6.
ResultSet rs = ...;
//Clob c = rs.getClob(1);  //не используем клоб
 byte [] data = rs.getBytes();  //вернет данные как есть

//а затем что угодно с ними делать:
String xml =  new  String(data);
//и т.п.

Так выгружается объект длинной 0 байт. Скорей всего происходит ошибка при трансформации стринг в байт. Шас попробую через ByteArrayOutputStream.
...
Рейтинг: 0 / 0
21.09.2007, 18:55:01
    #34818882
unicornmirage
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Ashitkin.Alex
Так выгружается объект длинной 0 байт. Скорей всего происходит ошибка при трансформации стринг в байт. Шас попробую через ByteArrayOutputStream.

если есть ошибка - то какова? а вообще странно, я таким методом часто пользуюсь... правда на BLOB-полях.
...
Рейтинг: 0 / 0
21.09.2007, 19:03:51
    #34818899
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Denis Popov Ashitkin.Alex
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
                Clob clob = resultSet.getClob( 1 );	
                Reader in = clob.getCharacterStream();
	     PrintWriter out = response.getWriter();
                BufferedReader br =  new  BufferedReader(in); 
	     out.println( out.getCharacterEncoding())
			     do 
                  { 
                    line = br.readLine();
	           	    out.println(line);
			      }
                while  (line !=  null ); 
...  

Попробуй просто:
Код: plaintext
out.println(clob.getSubString( 1 , ( int )clob.length()));


Попробовал. Результат то же, что и оригинале. Файл выводиться в неправильной кодировке.
...
Рейтинг: 0 / 0
21.09.2007, 19:05:02
    #34818902
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
unicornmirage
если есть ошибка - то какова? а вообще странно, я таким методом часто пользуюсь... правда на BLOB-полях.
Я не знаю. Почему то вылетает 0 байт и все. Пока я точно не знаю почему.
...
Рейтинг: 0 / 0
21.09.2007, 19:09:50
    #34818919
unicornmirage
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Ashitkin.Alex unicornmirage
если есть ошибка - то какова? а вообще странно, я таким методом часто пользуюсь... правда на BLOB-полях.
Я не знаю. Почему то вылетает 0 байт и все. Пока я точно не знаю почему.

может у тебя с порядком полей не так? и не оттуда читаешь
сделай вместо этого:
Код: plaintext
1.
"select * from clob_test where id=3"

явно:
Код: plaintext
1.
select YOUR_CLOB_FIELD_NAME from clob_test where id= 3 
...
Рейтинг: 0 / 0
21.09.2007, 19:23:25
    #34818937
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Частично помогло следующее:.
Код: plaintext
 String Encoded =  new  String(FromClob.getBytes("Windows-1251"),"UTF-8");

Сделал по следующим соображениям - в базе у меня вся кириллица в Windows-1251. В заголовке xml стоит encoding=UTF-8. Следовательно мне надо мою кириллицу из файла переписать в UTF-8 и отправить. Но помогло лишь частично. Кое где косяки с кодировкой по прежнему встречаются. В основном на букве И.
...
Рейтинг: 0 / 0
21.09.2007, 19:37:37
    #34818965
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Почему то Именно И в верхнем регистре не отображается. Мистика какая то.
...
Рейтинг: 0 / 0
21.09.2007, 19:56:53
    #34818993
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
А В JSP тоже самое? У меня в базе кодировка UTF8, создал таблицу:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
create table TEST_LOB (
    test_lob_id number( 9 )
  , cdata clob
  , constraint PK_TEST_LOB primary key (test_lob_id)
);

insert into TEST_LOB (test_lob_id, cdata)
  values ( 1 , 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNMйцукенгшщзфывапролдячсмитьЙЦУКЕНГШЩЗФЫВАПРОЛДЯЧСМИТЬ');
commit;

Код JSP:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
<%@ page  import ="java.sql.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE HTML  PUBLIC  "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>Clob Test</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<%
  Connection con =  null ;
  Statement st =  null ;
  ResultSet rs =  null ;
   try  {
    DriverManager.registerDriver( new  oracle.jdbc.OracleDriver());
    con = DriverManager.getConnection("jdbc:oracle:thin:@<host>:<port>:<SERVICE_NAME>", "<user>", "<pass>");
    st = con.createStatement();
    rs = st.executeQuery("select cdata from TEST_LOB where rownum = 1");
     if  (rs.next()) {
      Clob clob = rs.getClob("cdata");
      String sClob = clob.getSubString( 1 , ( int ) clob.length());
      out.println(sClob);
    }
  }  catch  (SQLException e) {
    out.println(e.getMessage());
  }  finally  {
     if  (rs !=  null ) { try  {rs.close();}  catch  (SQLException e2) {} }
     if  (st !=  null ) { try  {st.close();}  catch  (SQLException e2) {} }
     if  (con !=  null ) { try  {con.close();}  catch  (SQLException e2) {} }
  }
%>
</body>
</html>

Все буквы видны нормально.
...
Рейтинг: 0 / 0
22.09.2007, 13:33:28
    #34819422
Ashitkin.Alex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Косяки с кодировкой при CLOB через сервлет.
Спасибо большое всем за помощь!
Ситуация разрешилась. А проблема была в следующем. Изначально шаблон создавался в MS Word. Так вот это самое ПО, несмотря на то что в загловке документа ставит кодировку UTF-8, кириллические символы записывает в Windows-1251. Таким образом, в
Код: plaintext
Writer
пытается читатать и писать символы UTF-8, часть которых находящится в кодировке cp1251. В результате кракозяблы. Решил проблему переделкой исходного документа - скопировал его код и создал новый документ в единой кодировке Windows-1251. В коде сервлета везде использую только эту кодировку. Спасибо еще раз за помощь!
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Косяки с кодировкой при CLOB через сервлет. / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]