收到来自webform的MariaDB中的阿拉伯语/希伯来语

时间:2018-03-05 00:40:00

标签: spring-mvc apache-poi mariadb

我有一个小型的Spring 4应用程序,它从表单接收数据,将其保存在MariaDB中,将其显示在网页上,如果被要求返回使用Apache POI写入xls(MS Excel)文档的数据。 该应用程序适用于英文文本。

以下是我运行以创建和填充db表的命令:

CREATE DATABASE testdb COLLATE 'utf16_general_ci';
use testdb;
create table testtable( id INTEGER PRIMARY KEY AUTO_INCREMENT,   text1 VARCHAR(100),   text2 VARCHAR(100),   text3  VARCHAR(200));
INSERT INTO testtable (text1,text2,text3) VALUES ('אבג','דהו','זחט');

这是用于显示和发出请求的JSP页面:

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-16">
</head>
<body>
<table border=1>
<tr><th>TEXT1</th><th>TEXT2</th><th>TEXT3</th></tr>
<c:forEach items="${rowList}" var="row">
    <tr>
        <td>${row.getText1()}</td>
        <td>${row.getText2()}</td>
        <td>${row.getText3()}</td>
    </tr>
</c:forEach>
<tr><td><br><form method="GET" action="/clear"><input type="submit" value="CLEAR TABLE" /></form></td>
<td><br><form method="GET" action="/getxls"><input type="submit" value="download XLS file" /></form></td>
<td></td>
</tr>
</table>
<br>
<table border=1>
<tr><td>
<form method="POST" action="/add" accept-charset="UTF-16" >
<label>TEXT1</label>
<input type="text"  name="text1" /><br>
<label>TEXT2</label>
<input type="text" " name="text2" /><br>
<label>TEXT3</label>
<input type="text"  name="text3" />
<br>
<input type="submit" />
</td></tr>
</table>
</form>
</body>
</html>

这是应用程序的单个控制器:

@Controller
public class HomeController {

    @Autowired
    UserDao userDao;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(ModelMap model){
        model.addAttribute("rowList", userDao.getUserList());
        return "home";
    }
    @RequestMapping(value = "/clear", method = RequestMethod.GET)
    public String clearTable(){
        userDao.deleteAllUsers();
        return "home";
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addCoding(
        @RequestParam("text1") String t1,
        @RequestParam("text2") String t2,
        @RequestParam("text3") String t3,
        ModelMap model
    ) throws Exception{
        User b = new User(java.net.URLDecoder.decode(t1,"UTF-16"), t2, t3);
        userDao.addUser(b);
        model.addAttribute("rowList", userDao.getUserList());
        return "home";
    }

    @RequestMapping(value = "/getxls", method = RequestMethod.GET )
    public void export1( HttpServletResponse response ) throws IOException {
        List<User> users = userDao.getUserList();

        Workbook wb = new HSSFWorkbook();
        CreationHelper createHelper = wb.getCreationHelper();
        Sheet sheet = wb.createSheet("new sheet");

        // creating headers for data columns
        Row row = sheet.createRow(0);
        row.createCell(0).setCellValue("TEXT1");
        row.createCell(1).setCellValue("TEXT2");
        row.createCell(2).setCellValue("TEXT3");

        int rowIndex = 1;

        for(User user : users){
            row = sheet.createRow(rowIndex);
            row.createCell(0).setCellValue(createHelper.createRichTextString(user.getText1()));
            row.createCell(1).setCellValue(createHelper.createRichTextString(user.getText2()));
            row.createCell(2).setCellValue(user.getText3());

            rowIndex++;
        } 

        response.setHeader("Content-Disposition","attachment; filename=data.xls");

        ServletOutputStream out = response.getOutputStream();
        wb.write(out);
        out.flush();
        out.close();
    }
}

控制器中的数据对象称为User,但对于db id和三个int来说它实际上只是String

使用与提交它的MariaDB控制台相同的希伯来语输入填写表单会产生以下结果: Chromium request details

MariaDB select result

XLS file content

在所有三个结果显示中,第1行和第3行的内容相同。 (或者至少是输入) 使用MariaDB控制台输入第1行。 第3行输入了网页。 如何处理Web请求,以便在xls文件中第1行和第3行是相同的? 另外,如何在网页上正确显示第1行的数据?

2 个答案:

答案 0 :(得分:0)

更正JPS页面: 1)添加

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="ISO-8859-1"%>

到文档的顶部,这将正确显示从数据库中提取的有效数据。

2)在<form> rag中,将属性accept-charset的值从UTF-16更改为ISO-8859-1。这将以&#xxxx;的形式返回阿拉伯语和希伯来语字符,其中每个x都是十进制数字。

校正逻辑 - 将所述&#xxxx;个字符转换为正确的阿拉伯语/希伯来语字符: 希伯来语'Aleph'='א'传递为&#1488;。 在java String.valueOf(Character.toChars(Integer.parseInt("1488", 10)));中将返回正确的'א'字符;所以我添加了以下函数来在控制器中输入第一个东西:

    public static String y(String txt){

        String formatedString = "";
        char[] charArr = txt.toCharArray();
        for (int i=0; i<charArr.length; i++){
            if(charArr[i] != '&')
                formatedString += charArr[i];
            else {
                if (i+5 <= charArr.length && charArr[i+1] == '#'){
                    String temp = "";
                    for (int j=i+2;j<=i+5;j++)
                        temp += charArr[j];
                    if (temp.matches("-?\\d+(\\.\\d+)?")){
                        formatedString += String.valueOf(Character.toChars(Integer.parseInt(temp, 10)));
                        i=i+6;
                    }
                } else
                    formatedString += charArr[i];
            }
        }
        return formatedString;
    }

答案 1 :(得分:0)

使用utf-16。使用UTF-8,在MySQL内部称为utf8或utf8mb4。

在连接时,您必须指定客户端使用的编码。

表中的列必须声明为CHARACTER SET utf8(或utf8mb4)。

(阿拉伯语和希伯来语都得到处理。)

如果您确实在客户端使用UTF-16编码,则可以使用utf16进行连接。但我建议在表格中使用utf8或utf8mb4。 MySQL将动态转换。