一、生成图片验证码(一般在登陆、注册、找回密码等使用)
(1)生成图片类
@Component
public class RandomValidateCode {
/**
* 生成代码
*
* @return
*/
public static String createValidateCode(int size) {
String seed = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
int len = seed.length();
char[] p = new char[size];
for (int i = 0; i < size; i++) {
p[i] = seed.charAt((int) Math.floor(Math.random() * len));
}
return new String(p);
}
//产生随机数
private final Random random = new Random();
private final String randString = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";// 随机产生的字符串
private final int width = 135;// 图片宽
private final int height = 40;// 图片高
private final int lineSize = 50;// 干扰线数量
private final int stringNum = 4;// 随机产生字符数量
private final int fontSize = 30;// 随机产生字符数量
/**
* 生成随机图片
*/
public void getRandcode(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
BufferedImage image = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
g.fillRect(0, 0, this.width, this.height);
g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, this.fontSize));
g.setColor(this.getRandColor(110, 133));
// 绘制干扰线
for (int i = 0; i <= this.lineSize; i++) {
this.drawLine(g);
}
// 绘制随机字符
String randomString = "";
for (int i = 1; i <= this.stringNum; i++) {
randomString = this.drawString(g, randomString, i);
}
//删除保存的图片验证
session.removeAttribute(Constants.RANDOM_CODE_KEY);
//保存的图片验证
session.setAttribute(Constants.RANDOM_CODE_KEY, randomString);
// System.out.println(randomString);
g.dispose();
try {
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 将内存中的图片通过流动形式输出到客户端
ImageIO.write(image, "JPEG", response.getOutputStream());
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取随机的字符
*/
public String getRandomString(int num) {
return String.valueOf(this.randString.charAt(num));
}
/**
* 绘制干扰线
*/
private void drawLine(Graphics g) {
int x = this.random.nextInt(this.width);
int y = this.random.nextInt(this.height);
int xl = this.random.nextInt(13);
int yl = this.random.nextInt(15);
g.drawLine(x, y, x + xl, y + yl);
}
/**
* 绘制字符串
*/
private String drawString(Graphics g, String randomString, int i) {
g.setFont(this.getFont());
g.setColor(new Color(this.random.nextInt(155), this.random.nextInt(123), this.random.nextInt(176)));
String rand = String.valueOf(this.getRandomString(this.random.nextInt(this.randString.length())));
randomString += rand;
g.translate(this.random.nextInt(3), this.random.nextInt(3));
g.drawString(rand, (this.width / this.stringNum - 14) * i, this.height - 7);
return randomString;
}
/**
* 获得字体
*/
private Font getFont() {
return new Font("Times New Roman", Font.CENTER_BASELINE, this.fontSize);
}
/**
* 获得颜色
*/
private Color getRandColor(int fc, int bc) {
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + this.random.nextInt(bc - fc - 16);
int g = fc + this.random.nextInt(bc - fc - 14);
int b = fc + this.random.nextInt(bc - fc - 18);
return new Color(r, g, b);
}
}
(2)常量
类Constants
public static final String RANDOM_CODE_KEY = "RANDOM_CODE_KEY";
(3)JSP页面 login.jsp
<script type="text/javascript">
var i = 1;
function fun() {
document.getElementById("pcode").src = "pcode.html?v=" + (i++); //翻下1张图片
}
</script>
<body>
<div style="margin: 0 auto; margin-top: 100px; background:snow">
<form method="post" action="doLogin.html" name="form1">
<p>
<input type="text" name="pcode">
<!-- 单击图片都可以换下一张 -->
<input id="pcode" type="image" src="pcode.html" οnclick="fun()">
<input type="submit" />
</p>
</form>
${error}
</div>
</body>
</html>
(4)控制类
@Controller
public class ToolController {
@RequestMapping("toPage")
public String toPage(@RequestParam String pageName) {
// return "/WEB-INF/jsp/"+pageName+".jsp";
return pageName;
}
// 随机产生的图片
@Resource
RandomValidateCode randomValidateCode;
@RequestMapping("/pcode")
public void pcode(HttpServletRequest request, HttpServletResponse response) {
randomValidateCode.getRandcode(request, response);
}
@RequestMapping("/doLogin")
public String doLogin(HttpServletRequest request,
HttpServletResponse response, @RequestParam String pcode) {
// 获得图片验证码
String code = (String) request.getSession().getAttribute(
Constants.RANDOM_CODE_KEY);
// 判断是否是相同
if (pcode.equals(code)) {
return "i18n"; // 跳转到i18n.jsp页面
} else {
if (pcode == null || pcode.equals("")) {
System.out.println("pcode=0==>");
} else {
// 保存错误消息
request.setAttribute("error", "验证码出错!");
}
return "login"; // 跳转到login.jsp页面
}
}
}
(5)效果
单击图片
输入的与图片验证不一致
输入一致,跳转到正确页面
二、国际化
常把I18N作为“国际化”的简称,是英文单词 internationalization的首末字符i和n。18为中间的字符数。
(1)
Spring通过实现MessageSource接口,来支持国际化
(2)
ResourceBundleMessageSource是一个常用的实现
(3)
使用LocaleResolver接口的实现类实现本地化信息的解析
(4)
使用LocaleChangeInterceptor实现本地化信息的监听
(1)在src/main/resources 创建i18n包下存放资源文件
message_en.properties
title=this is test internationalization
display=this is display
login.title=picture validate
message_zh.properties
title=\u6D4B\u8BD5\u56FD\u9645\u5316
display=\u6D4B\u8BD5\u663E\u793A
login.title=\u56FE\u7247\u9A8C\u8BC1
package com.hlx.filter;
import java.io.IOException;
import java.util.Locale;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.hibernate.validator.internal.util.privilegedactions.NewInstance;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
/**
* 过滤器
* @author Administrator
*
*/
public class LocalFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
// 默认的语言
String language="zh";
//用cookie来获取
Cookie[] cookies = ((HttpServletRequest)arg0).getCookies();
//判断
if (cookies!=null &&cookies.length>0) {
for (Cookie cookie : cookies) {
//判断是不是language
if("language".equals(cookie.getName())){
language = cookie.getValue(); //获得值
}
}
}
System.out.println("change in language="+language);
//保存语言
((HttpServletRequest)arg0).getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale(language));
//过滤下一个链
arg2.doFilter(arg0, arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
必须在web.xml文件中配置
<!-- 配置过滤器 -->
<filter>
<filter-name>LocalFiter</filter-name>
<filter-class>com.hlx.filter.LocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LocalFiter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LocalFiter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- 配置默认的语言,过滤器 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="zh"/>
</bean>
<!-- 过滤器 (语言发生变化时触发) -->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>
<!--(3) 配置资源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n/message"/> <!-- 资源文件的名称 -->
<property name="defaultEncoding" value="utf-8"/><!-- 文件编码 -->
<property name="useCodeAsDefaultMessage" value="true"/><!-- 不存在对应的资源,那么就用code名字为值 -->
</bean>
(4)Jsp页面 i18n.jsp
<script type="text/javascript">
function changLang(lang){
//日期
var days = new Date();
//1年
days.setDate(days.getDate()+365);
//会话
document.cookie = "language="+lang+";expires="+days.toGMTString();
//刷新
location.reload();
}
</script>
<body>
<a href="javascript:changLang('en')">英文</a>
<a href="javascript:changLang('zh')">中文</a>
<div style="margin: 0 auto; margin-top: 100px; background:snow">
<spring:message code="display"></spring:message>
</div>
</body>
(5)效果,可以来回的切换中英文