国际化与 Web 安全认证
面向海外用户,界面文字不能写死中文;后台接口不能裸奔让任何人调。这一章补两块JavaEE 标准能力:国际化(多语言)和容器内置认证(表单/BASIC/HTTPS)。Spring 时代这些都被封装了,但底层原理要知道。
国际化 i18n:同一句"登录",按语言出不同字
i18n 是 internationalization 的缩写(i 后面 18 个字母)。大白话:把所有界面文字抽到 .properties 文件里,中文一个文件、英文一个文件,运行时按用户语言挑对应文件取字。
| 文件 | 内容 |
|---|---|
messages_zh_CN.properties | login.title=登录(简体中文) |
messages_en_US.properties | login.title=Login(美式英文) |
messages.properties | 缺省兜底文件,找不到对应语言时用它。 |
// 根据请求头里的 Accept-Language 挑语言文件,取 key 对应的字
@WebServlet("/i18n")
public class I18nServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
// 用户语言:浏览器自动带 Accept-Language: zh-CN
Locale locale = req.getLocale();
// 去 classpath 下找 messages_xx.properties
ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);
String title = bundle.getString("login.title");
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().println("<h1>" + title + "</h1>");
}
}
.properties 默认是 ISO-8859-1 编码,直接写中文会乱码。要么文件存成 ASCII 转义(\u4E2D\u6587),要么 Spring 的 MessageSource 直接读 UTF-8 的 .properties(配 defaultEncoding=UTF-8)。新项目强烈建议后者。
容器内置认证:不用自己写登录页的原始方案
Servlet 容器(Tomcat)自带一套认证机制,在 web.xml 里配一下就能用,不用自己写登录校验。了解即可,现在项目都用 Spring Security。
| 认证方式 | 人话 |
|---|---|
| BASIC | 浏览器弹个原生对话框要账号密码,Base64 编码明文发——必须配 HTTPS,否则等于裸奔。 |
| FORM | 用自己写的登录页提交,容器帮你校验、建 Session,比 BASIC 灵活。 |
| DIGEST | 密码摘要传输,比 BASIC 安全但不如 HTTPS,基本淘汰。 |
<!-- web.xml 里配 FORM 认证(Jakarta EE 命名空间) -->
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint><role-name>ADMIN</role-name></auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
</form-login-config>
</login-config>
HTTPS 与 SSL:别让密码裸奔在网线里
HTTP 是明文,你在公共 WiFi 下登录,中间人能直接抓到你的账号密码。HTTPS = HTTP + SSL/TLS,传输内容加密,还能验证服务器身份。
论三句话记住
① 生产环境登录、支付、传 token 的接口必须 HTTPS,HTTP 上跑 BASIC 认证等于把密码贴街上。② Tomcat 要配证书(JKS/P12),现在一般前面放 Nginx/网关统一终止 SSL,应用本身跑 HTTP 即可。③ Cookie 配 Secure 属性,只在 HTTPS 下才发,配合 HttpOnly 双保险。
1.(概念题)ResourceBundle 怎么挑语言文件?找不到怎么办?
查看答案
答案:按 messages_语言_国家.properties 找(如 zh_CN、en_US),找不到逐级退到不带后缀的 messages.properties 兜底。Locale 来自请求头 Accept-Language。
2.(安全题)BASIC 认证为什么必须配 HTTPS?
查看答案
答案:账号密码只是 Base64 编码,不是加密,抓包一解码就是明文。只有 HTTPS 加密传输才不会被中间人截获。
3.(安全题)Cookie 的 Secure 和 HttpOnly 分别防什么?
查看答案
答案:HttpOnly 防 XSS 偷 Cookie(JS 读不到);Secure 防在 HTTP 明文下传 Cookie(只在 HTTPS 才发)。两个一起上才稳。