Spring boot alkalmazás ékezetes karakterek STS-ből vs CMD-ből

0 értékelés
31 megtekintés
thork (16 pont) kérdezte Nov 5.
Sziasztok.

Olyan gondom adódott, hogy fejlesztettem egy Spring Boot - Thymeleaf alkalmazást mariaDB adatbázissal. Tud beolvasni csv file-t. Ha STS-ből indítom az alkalmazást és olvasatok be csv file-t akkor a karakterek rendesen megjelennek, azonban ha cmd-ből "java - jar ...." akkor a csv beolvasását követően valamiért az ékezetes karakterek helyett krikszkrakszok lesznek.

Ezt hogy tudom kiküszöbölni ?

Válaszotokat köszönöm szépen

1 Válasz

0 értékelés
tkiss Szakértő (308 pont) válaszolta meg Nov 5.
Krisz kiválasztva Nov 9.
 
Legjobb válasz

Szia!

Sajnos ebből nem látszik, hogy milyen enkódolású csv-t és hogyan olvasol be. Ha jól tippelem, beolvasásnál charset-et nem adtál meg, így a jvm default charset-jét használja, ami a te esetedben eclipse alatt eltér attól, mint amikor parancssorból indítod.

  • Egyrészt lehetőleg már beolvasásnál add meg az adott file-nak megfelelő charset-et(a csv enkódolását egy notepad++ alatt megnézheted).
  • Ha ezt valamiért nem akarod, megpróbálhatod indításnál hozzácsapni a következő VM argumentumot: -Dfile.encoding=UTF-8
Update(file feltöltés encoding ellenőrzésre egy példa):
  • A "-Dfile.encoding=UTF-8" vm argumentumot add hozzá indításnál, hogy a default charset UTF-8 legyen(ez nem kötelező, de enélkül ha csak mondjuk egy System.out.println-el ki akarod írni az UTF-8 content-et és a default charset-ed nem az, akkor nem fog helyesen megjelenni, mert az is a default charset-et használja)
  • A validációhoz vedd fel az alábbi maven dependenciát(több hasonló library létezik, ez csak egy): 
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-parsers</artifactId>
    <version>1.4</version>
</dependency>
  • Magára a validációra egy példa:
    @PostMapping("/fileupload")
    public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) throws IOException{
        if(!isContentUTF8(file.getBytes())) {
            //kezeled a hibát, hogy a user nem utf8 content-et töltött fel
        }
       
        String content=new String(file.getBytes(),StandardCharsets.UTF_8);    
        System.out.println(content);

        return ResponseEntity.ok().build();
    }

    private boolean isContentUTF8(byte[] content)
    {
        CharsetDetector charsetDetector = new CharsetDetector();
        charsetDetector.setText(content);
        CharsetMatch[] charsetMatches=charsetDetector.detectAll();
        for(CharsetMatch match:charsetMatches) {
            if(match!=null && StandardCharsets.UTF_8.name().equals(match.getName())) {
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

Üdv.: Tamás

thork (16 pont) szólt hozzá Nov 5.
Az argomentumos dolog működött, viszont jobban szeretném ha a programban már megoldódna valahogy. a csv file-nál a kódolásnál UTF-8-at ír, beolvasáshoz MultipartFile-t használok, de nem látom hogy hol lehetne beállítani a charset-et, mikor beolvasom a file-t , vagy mikor elmentem adatbázisban a file-ban található adatokat?
Válaszod nagyon szépen köszönöm.
tkiss Szakértő (308 pont) szólt hozzá Nov 5.
Ja hogy MultipartFile? Abból ahogy írtad, úgy értelmeztem, hogy az alkalmazásod egy csv-t olvas fel a fájlrendszerről, de te file-t töltesz fel multipart/formdata-ként. Na most arra, hogy a felhasználó milyen enkódolású fájlt akar majd neked feltölteni, azt előre nem tudhatod. Ha biztos vagy benne, hogy csak UTF-8-at, akkor nem baj ha beállítottad a default-ot UTF-8-ra a file.encoding-al. Ha esetleg validálni akarod a feltöltött file enkódolását, arra vannak különböző library-k(pl. Apache Tika), amikkel runtime megállapíthatod(bár amennyire eddig tapasztaltam, elég felemás a megbízhatóságuk).
Ha pedig már megállapítod a charset-et, át is tudod akár konvertálni neked tetszőbe.
thork (16 pont) szólt hozzá Nov 6.
Biztos hogy UTF-8-at fog feltölteni a felhasználó (ha jót akar magának :) )
Nem teljesen tiszta, hogy hol kell beállítanom ezt a file.encoding-ot , próbáltam ott ahol megkapja a back end a file-t, de ott nem ad fel ilyen metódust a file.-nak. Rossz helyen kapisgálok ?
tkiss Szakértő (308 pont) szólt hozzá Nov 6.
Egyrészt azt nem értem miért kérded hogy hol kell beállítani a file.encoding-ot, ha egy előző hozzászólásodban azt írtad, hogy azzal működött(indításnál megadva a "-Dfile.encoding=UTF-8"-at a default charset-ed UTF-8 lesz), másrészt úgy érzem inkább itt már az a kérdés, hogy hogyan tudod validálni, hogy a user milyen content-et töltött fel. Update-eltem eszerint a választ.
thork (16 pont) szólt hozzá Nov 6.
Úgy értettem, hogy működik, mikor indítom cmd-ben "java -jar -Dfile.encoding=UTF-8 programom.jar" így működik rendesen a karakterek megjelenítése. Nem nagyon értek hozzá, de ha jól sejtem, akkor minden indításkor ezt a "hosszabb" parancsot kell beírni, és jobban szeretném , egyszerűbb lenne ha ezt a "-Dfile.encoding=UTF-8"-at nem kellene mindig beírnom a parancssori indításkor, ezt valahogy meg lehet oldani ?
Köszönöm szépen az update-et megcsinálom azt is szerintem.
tkiss Szakértő (308 pont) szólt hozzá Nov 6.
Szerintem ugyan ennyitől még nem lesz túl hosszú a parancs, de
-az indító parancsot egy shell script-be(windows-on batch file-ba) is foglalhatod(ha nagyon zavarna a parancs hossza én ezt tenném)
-a JAVA_TOOL_OPTIONS környezeti változónál is megadhatod az argumentumot
-próbálkozhatsz kód szinten a "System.setProperty("file.encoding","UTF-8");"-al is, de mivel a java több helyen cache-eli a default charset-et, ezért  érdemesebb indulásnál megadni.
thork (16 pont) szólt hozzá Nov 7.
Köszönöm az infót, okos ötlet ez a batch file, nem értem nekem hogy nem jutott eszembe :) .
...