Van egy adatbázis benne egy adattábla:
CREATE DATABASE siteDB DEFAULT CHARACTER SET utf8;
USE siteDB;
CREATE TABLE blog(
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
created DATETIME DEFAULT '0000-00-00 00:00:00',
modified DATETIME DEFAULT '0000-00-00 00:00:00',
title VARCHAR(255) NOT NULL,
text TEXT NOT NULL
)DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Készülget hozzá egy java EE-s alkalmazás. Minden fájl utf-8-ba mentve, mint látható a fentiből
az adatbázis is és az adattábla is utf-8-ban van. (igen a két szöveges mező is).
A problémám az, hogy a Mysql-be nem utf-8-ként mentődik, hanem az ékezetes betűk helyett mindenféle krix-krax van. Fontos tehát, hogy nem az adatbázisból való kiolvasással van a gond, hanem a beírással.
Mivel korábban foglalkoztam php-vel, így kipróbáltam, íme egy példa:
<?php
$link = mysql_connect('localhost','user','pass');
if (!$link) {
die('Could not connect to MySQL: ' . mysql_error());
}
echo 'Connection OK
';
$db = mysql_select_db("siteDB");
if ($db != true){
echo "Adatbázis kiválasztás sikertelen";
die();
}
echo "ok
";
$str="INSERT INTO blog (created, modified, title, text) VALUES(now(), now(),'éáő', 'éáőpé')";
//mysql_query("SET NAME 'utf8'");
mysql_query("SET CHARACTER SET 'utf8'"); // <- ha ez benne van, akkor oké
mysql_query($str);
mysql_close($link);
?>
A fenti példában a comment szerint ha beírom, a "mysql_query("SET CHARACTER SET 'utf8'");" sort, akkor jól mentődnek el az ékezetes karakterek, ha nem akkor a már ismertetett krix-kraxos történet jön elő.
Tehát valami mysql_query("SET CHARACTER SET 'utf8'");-hez hasonlót szeretnék javaban.
Ami megvan:
response.setContentType("text/html; charset=utf-8");
//request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
A html oldalak így generálódnak:
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Amiket kipróbáltam, de nem segítettek:
1) google szerint, amikor csatlakozom a adatbázishoz, akkor paraméterként átadható az "encoding", tehát itt:
con = DriverManager.getConnection("jdbc:mysql://localhost/siteDB?IDE_JON_AZ_ENCODING",
"user", "pass");
Már nem emlékszem mi volt az IDE_JON_AZ_ENCODING, de kipróbáltam és nem működött. :)
2)Mint php-nél próbáltam egy query-t csinálni:
String sql = "INSERT INTO blog ....";
Connection con = null;
PreparedStatement ps = null;
Statement stmt = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost/siteDB",
"user", "pass");
Statement st = con.createStatement();
st.executeQuery("SET NAMES 'utf8'");
st.executeQuery("SET CHARACTER SET 'utf8'");
st.executeUpdate(sql);
st.executeQuery("SET CHARACTER SET 'utf8'"); helyett próbáltam sima execute-ot -> semmi.
Továbbra is rosszul menti a karaktereket az adatbázisba.
3) my.cnf módosítása. Ez megtörtént, de sokra nem megyek vele, egyrészt mert nem javult meg ettől semmi, másrészt meg ahova majd feltölteném ott se tudom módosítani a my.cnf-et...
A kérdés tehát adott, valamiért az adattáblába rosszul mentődnek el a sorok,
A segítséget, ötletet előre is köszi!
- 5159 megtekintés
Hozzászólások
szia!
pl
jdbc:mysql://host/database?useUnicode=true&characterEncoding=UTF-8
- A hozzászóláshoz be kell jelentkezni
Szia,
na ezt akartam írni az 1)-be csak nem emlékeztem rá pontosan.
Kipróbáltam újra, de nem működik, továbbra is hülye karakterek kerülnek elmentésre (pl.: éáűé).
Azért köszi.
- A hozzászóláshoz be kell jelentkezni
Ha programot irsz, fontos megerteni, mi miert tortenik. A mysql-nek teljesen mindegy, hogy mi a mezo enkodingja, vagy barmi, csak meg kell adni neki, hogy eppen mivel akarsz kommunikalni (SET NAMES - ezt a jdbc driver megcsinalja a fenti url parameterekkel), a tobbit atkonvertalja. Ebbol rengeteg problema szokott lenni, pl egy latin mezobe ha latinkent utf karaktereket kuldesz, azt eltarolhatja, mukodhet is jo darabig (ha beirva es kiolvasva is hibas set names-el van), de 1-2 dump/restore, mezo konverzio, stb utan akar visszaallithatatlanul truncatelodhet az informacio. Ezt csak azert irom, mert tenyleg fontos. Jelen esetben van egy olyan elkepzelesem, hogy a forraskodba irt stringedet nem menti jol el, milyen platformon dolgozol, mi a file.encoding? Vagy mast is rosszul insertal?
- A hozzászóláshoz be kell jelentkezni
Azt hiszem most kezdem egy picit hülyének érezni magam. Szóval:
Eddig amit a Servletből akartam elmenteni azokat az adatokat nem a forrásfájlba írta be, hanem egy form-ból szedtem ki. Ha átírom fix szövegre a forrásfájlban akkor jól működik (mint a php-s példánál), de ha formból kapom az adatot, akkor áll fent a probléma, amiért nyitottam ezt a topicot.
1) A formból így szedem ki az adatot:
String title = request.getParameter("title");
És azt a "title"-t mentem el az adatbázisba (most az mindegy hogy nincs ellenőrzés és a title tartalma bármi lehet)
2) A form kiíratása:
out.print("
");
out.print("Cím:
");
out.print("Tartalom:
");
out.print("");
out.print("
");
out.print("
");
out.print("
");
out.print("
");
3) Részlet annak az oldalnak a forrásából, amiben a form van:
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Tehát akkor gondolom azzal van gond, hogy a usetől nem utf8-ban kapom az adatot? Ezzel mit kezdjek?
Bár így ez (Jelen esetben van egy olyan elkepzelesem, hogy a forraskodba irt stringedet nem menti jol el, milyen platformon dolgozol, mi a file.encoding? Vagy mast is rosszul insertal?) már nem annyira érdekes, de leírom.
Linux (Slamd64), minden fájl utf-8-ba mentve, IDE: eclipse.
- A hozzászóláshoz be kell jelentkezni
OK. Akkor a formból jön rosszul. Rossz iranyba indultunk :)
Valoszinuleg mar a kliens kuldi rosszul es nem kerul konvertalasra, vannak ilyen par soros servlet filterek mindenfele a google-ben erre a problemara. (Ha ez a problemad.)
Amugy miert csinalsz out.print() -el web alkalmazast? Ennyi erovel irhatnad C-ben is..
- A hozzászóláshoz be kell jelentkezni
(A fentiben a form kiiratása persze nem így néz ki csak rosszul jelenik meg.)
"Amugy miert csinalsz out.print() -el web alkalmazast?"
Ez úgy néz ki, hogy minden oldal include-ol egy jsp-t:
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
request.getRequestDispatcher("/Menu.jsp").include(request, response);
Ez a Menu.jsp egy olyan jsp ami tartalmaz egy .css-t (< link rel='stylesheet' type='text/css' href='blog.css' / >),
majd div-ekkel elkezdi kirajzolni az oldalt: az oldal tetejét, a bal oldali menüt, majd kiirja a lényegi rész "nyitó" divjét, és nagyjából ennyi a Menu.jsp.
Tehát a tényleges Servletekben nem sok html-van (form például), 0 css, stb.
Mivel most ismerkedem a servletekkel és jsp-vel, nem tudom hogy jól csinálom-e ezt így. Ha csak ennyi miatt kell az out.print, akkor az még oké, vagy eleve rosszul állok a dologhoz? Ez esetben mit javasolnál hogyan?
Azt a filteres ötletet köszi, megpróbálok keresgélni. (lehet csak holnap ma már lefáradtam)
Köszönöm a segítséged, és bocsi, hogy először "átvertelek" és nem is az volt a hiba, mint amit írtam.
- A hozzászóláshoz be kell jelentkezni
Senki nem programozik ma mar igy servlet-et. Onszopatas.
Probald ki a grails-t, ahol teljesen egyszeruen, ugyanakkor kurrens technologiakkal (hibernate, spring stb) lehet haladni. Egy kis pl. ORM tapasztalat 100x tobbet er, mint hogy ossze tudod-e reszelni servletben nativ JDBC-vel ezt a charset dolgot.
- A hozzászóláshoz be kell jelentkezni
Köszi utána fogok nézni a grailsnak!
Az viszont igaz, hogy szeretem látni a dolgok mélyén mi van, ezért is nem bánom ha servletekkel, jsp-vel szívok. (Szívem szerint FastCGI-t tanulnám C/C++-ban írva, de félek nem sokra mennék vele a jövőben. :) )
Még egyszer, köszi a segítséget!
- A hozzászóláshoz be kell jelentkezni
Azt mindig jo tudni, mi van a dolgok melyen, csak kerdes, meddig erdemes lemenni? Nem csak hogy a jovoben mire mennel vele, hanem hogy egyaltalan elkeszulne-e valaha... :)
- A hozzászóláshoz be kell jelentkezni
Na szóval, mint kiderült az volt a gond, hogy az adatokat a usertől kértem be form-on keresztül, azt viszont nem utf8-ban kaptam meg, így ha elmentettem egy adatbázisba konvertálás nélkül, akkor az hibásan mentődött el.
Megoldás:
String title = new String(request.getParameter("title").getBytes(), "UTF-8");
És ezt a "title"-t már el lehet menteni.
Szerk.:
Ez itt OFF, de hátha más is belefut:
javaból sokáig nem tudtam hozzáférni az adatbázishoz, konzolból, vagy php-vel igen.
A hiba abból eredt, hogy a Slackware-es (nálam: Slamd64-es) mysql rc script elég furán viselkedik, alapértelmezetten a beállító fájl egyik opcióját figyelmen kívül hagyja (felülírja):
Az rc.mysql-ben ezt a részt keresd:
###
# To allow outside connections to the database comment out the next line.
# If you don't need incoming network connections, then leave the line
# uncommented to improve system security.
SKIP="--skip-networking"
Írd át:
#SKIP="--skip-networking"-ra és JDBC-vel is eléred az adatbázisokat.
(Mire én erre rájöttem...)
- A hozzászóláshoz be kell jelentkezni