Servlet中doget()方法写文件发生中文乱码,如何解决?

作业需求:登陆注册系统中,注册时会调用一个方法来创建一个文件写入用户的密码、科目等信息,在doget()中调用该方法。随后在浏览器地址栏上写参数信息,科目的参数中有中文,结果看创建的文件该参数乱码了,显示一串问号。故登陆时也不能确认信息从而无法登陆。
PS:dopost()能较好实现,但作业任务要求doget()也实现,故提出此疑问。

调试时地址栏的输入:

http://localhost:8080/test3_1/register.do?email=1223@123.com&username=123&password=123123123&confirmedPasswd=123123123&subject=计算机

doget()相关代码

protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("utf-8");
        String subject = request.getParameter("subject");
        byte b[]=subject.getBytes("UTF-8");
        subject=new String(b,"UTF-8");

        String email = request.getParameter("email");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String confirmedPasswd = request.getParameter("confirmedPasswd");

        System.out.println(subject);
        List<String> errors = new ArrayList<String>();
        if (isInvalidEmail(email)) {
            errors.add("未填写邮件或邮件格式不正确");
        }
        if (isInvalidUsername(username)) {
            errors.add("用户名称为空或已存在");
        }
        if (isInvalidPassword(password, confirmedPasswd)) {
            errors.add("请确认密码符合格式并再次确认密码");
        }
        String resultPage = ERROR_VIEW;
        if (!errors.isEmpty()) {
            request.setAttribute("errors", errors);
        } else {
            resultPage = SUCCESS_VIEW;
            createUserData(email, username, password, subject);
        }
        request.getRequestDispatcher(resultPage).forward(request, response);

    }

写文件方法

 private void createUserData(String email, String username, String password,
            String subject) throws IOException {
        File userhome = new File(USERS + "/" + username);
        userhome.mkdir();
        BufferedWriter writer = new BufferedWriter(new FileWriter(userhome
                + "/profile.txt"));
        writer.write(email + "\t" + password + "\t" + subject);
        writer.close();
    }

显示页面html

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type"  content="text/html; charset=UTF-8" >
<title>注册会员</title>
</head>
<body>
    <h1>会员注册</h1>
    <form method='post' action='register.do'>
        <table bgcolor=#cccccc>
            <tr>
                <td>邮件地址:</td>
                <td><input type='text' name='email' size='25' maxlength='100'>
                </td>
            </tr>
            <tr>
                <td>用户名(最大16字符):</td>
                <td><input type='text' name='username' size='25'
                    maxlength='16'>
                </td>
            </tr>
            <tr>
                <td>密码(6到16字符):</td>
                <td><input type='password' name='password' size='25' maxlength='16'>
                </td>
            </tr>
            <tr>
                <td>确认密码:</td>
                <td><input type='password' name='confirmedPasswd' size='25' maxlength='16'>
                </td>
            </tr>
            <tr>
                <td>专业:</td>
                <td><select name="subject" size="1" >
                        <option value="计算机">计算机</option>
                        <option value="软件工程">软件工程</option>
                        <option value="网络工程">网络工程</option>
                </select></td>
            </tr>
            <tr>
                <td colspan='2' align='center'><input type='submit' value='注册'>
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

写后直接记事本打开,发现输入的subject参数一串问号。
已经查阅百度,写的编码或字符编码转换也应该加上了的,但还是不能解决。
希望有前辈补坑

加上这两行,稳稳的解决问题哈
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");

https://blog.csdn.net/liyuxing6639801/article/details/69487712

因为一般编译器默认的是 ISO-8859-1,不支持中文。
所以Get请求是ISO-8859-1 编码。
用这个方法就行了

将获取到的 ISO-8859-1 编码的subject 进行转码即可

 String subject = request.getParameter("subject");//此时乱码
 subject = changeCharset(subject);//此时转换为计算机
 public String changeCharset(String str)   throws UnsupportedEncodingException {
        if (str != null) {
            byte[] bs = str.getBytes(ISO_8859_1);//用旧的字符编码解码字符串。解码可能会出现异常。
            return new String(bs, UTF_8);//用新的字符编码生成字符串
        }
        return null;
    }

上面那个方法编码我定义为常量了

    public static final String UTF_8 = "UTF-8";
    public static final String ISO_8859_1 = "ISO-8859-1";

可以直接使用下面的

     public String changeCharset(String str)   throws UnsupportedEncodingException {
        if (str != null) {
            byte[] bs = str.getBytes("ISO-8859-1");//用旧的字符编码解码字符串。解码可能会出现异常。
            return new String(bs, "UTF-8");//用新的字符编码生成字符串
        }
        return null;
    }

(1)GET
String param = request.getParameter("param");
String x = new String(param.getBytes("iso8859-1"),"GBK");
(2)POST
request.setCharacterEncoding("GBK");
String param = request.getParameter("param");