web项目 Webroot下面的index.jsp页面的内容:
<%@ page language="java" pageEncoding="UTF-8"%>
<%
response.sendRedirect("start.do");
%>
<!--在index.jsp中使用 start.do 跳转到 /WEB-INF/jsp/user_login.jsp 受保护资源 -->
Web.xml中定义监听器
<listener>
<listener-class>
net.wanggd.mobile_scm.web.SysInit
</listener-class>
</listener>
net.wanggd.mobile_scm.web.SysInit是监听类,当weblogic或tomcat启动的时候加载
package net.wanggd.mobile_scm.web;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SysInit implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent event) {
ServletContext application = event.getServletContext();
//系统名称
String sysname = application.getInitParameter("sysname");
application.setAttribute("sysname", sysname);
//全局上下文路径
application.setAttribute("ctx", application.getContextPath());
}
}
需要实现2个方法
在user_login.jsp中有
<head>
<title>${sysname}</title>
<!—
sysname就是在监听器net.wanggd.mobile_scm.web.SysInit中定义的全局上下文 -->
</head>
验证码
Jsp页面验证码的显示和更换
<div class="validateCodeDiv" style="cursor:pointer;display:none" onclick="changeCode();">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td height="60">
请求验证码,使用servlet构建的,src指定访问servlet的地址
<img src="servlet/getVcode" id="imgVcode"/>
</td>
</tr>
<tr>
<td align="center" valign="middle" height="20" style="color:blue">若看不清,点图片换一张
</td>
</tr>
</table>
</div>
验证码之servlet代码
package net.wanggd.mobile_scm.web;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.beifeng.mobile_scm.utils.VCodeGenerator;
public class GetValidateCodeServlet extends HttpServlet {
private static final long serialVersionUID = 8244305529216943035L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
OutputStream os = response.getOutputStream();
VCodeGenerator vg = new VCodeGenerator(os);
String vcode = vg.drawCode();
os.close();
//把验证码放入session中
request.getSession().setAttribute("vcode", vcode);
}
}
验证码核心实现类
package net.wanggd.mobile_scm.utils;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
public class VCodeGenerator {
final private char[] chars = "2345678ABCDEFGHJKLMPQRSTUVWXYabcdefhkmnqrstuvwx"
.toCharArray();
private static String[] fontNames = new String[] { "Courier", "Arial",
"Verdana", "Georgia", "Times", "Tahoma" };
private static int[] fontStyle = new int[] { Font.PLAIN, Font.BOLD,
Font.ITALIC, Font.BOLD | Font.ITALIC };
private int width = 160;
private int height = 60;
private int charCnt = 4;
private int disturbLineNum = 10;
private OutputStream os;
public VCodeGenerator(OutputStream os) {
this.os = os;
}
public VCodeGenerator(OutputStream os, int width, int height, int charCnt) {
this.width = width;
this.height = height;
this.charCnt = charCnt;
this.os = os;
}
public String drawCode() throws IOException {
BufferedImage bi = new BufferedImage(this.width, this.height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.setColor(new Color(245, 245, 245));
g.fillRect(0, 0, this.width, this.height);
drawDisturbLine(g);
BufferedImage[] bis = new BufferedImage[charCnt];
char[] codes = generateCode();
for (int i = 0; i < charCnt; i++) {
bis[i] = generateBuffImg(codes[i]);
g.drawImage(bis[i], null, (int) (this.height * 0.7) * i, 0);
}
g.dispose();
ImageIO.write(bi, "gif", os);
return new String(codes);
}
private BufferedImage generateBuffImg(char c) {
String tmp = Character.toString(c);
Color forecolor = getRandomColor();
Color backcolor = new Color(255, 255, 255, 0);
String fontName = getRandomFontName();
int fontStyle = getRandomStyle();
int fontSize = getRandomSize();
int strX = (this.height - fontSize) / 2;
int strY = (this.height - fontSize) / 2 + fontSize;
double arch = getRandomArch();
BufferedImage ret = new BufferedImage(this.height, this.height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = ret.createGraphics();
g.setColor(backcolor);
g.fillRect(0, 0, this.height, this.height);
g.setColor(forecolor);
g.setFont(new Font(fontName, fontStyle, fontSize));
g.rotate(arch, this.height / 2, this.height / 2);
g.drawString(tmp, strX, strY);
g.dispose();
return ret;
}
private double getRandomArch() {
return ((int) (Math.random() * 1000) % 2 == 0 ? -1 : 1) * Math.random();
}
private Color getRandomColor() {
int r = (int) (Math.random() * 10000) % 200;
int g = (int) (Math.random() * 10000) % 200;
int b = (int) (Math.random() * 10000) % 200;
return new Color(r, g, b);
}
private String getRandomFontName() {
int pos = (int) (Math.random() * 10000) % (fontNames.length);
return fontNames[pos];
}
private int getRandomStyle() {
int pos = (int) (Math.random() * 10000) % (fontStyle.length);
return fontStyle[pos];
}
private int getRandomSize() {
int max = (int) (this.height * 0.98);
int min = (int) (this.height * 0.75);
return (int) (Math.random() * 10000) % (max - min + 1) + min;
}
private char[] generateCode() {
char[] ret = new char[charCnt];
for (int i = 0; i < charCnt; i++) {
int letterPos = (int) (Math.random() * 10000) % (chars.length);
ret[i] = chars[letterPos];
}
return ret;
}
private void drawDisturbLine(Graphics2D graphics) {
for (int i = 0; i < disturbLineNum; i++) {
graphics.setColor(getRandomColor());
int x = (int) (Math.random() * 10000) % (this.width + 1) + 1;
int x1 = (int) (Math.random() * 10000) % (this.width + 1) + 1;
int y = (int) (Math.random() * 10000) % (this.height + 1) + 1;
int y1 = (int) (Math.random() * 10000) % (this.height + 1) + 1;
graphics.drawLine(x, y, x1, y1);
}
}
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("d:/tmp.gif");
VCodeGenerator vg = new VCodeGenerator(fos);
vg.drawCode();
}
}
Js函数
使用jquery指定id为magVcode的img元素的src,这是使用了参数ts=new date().getTime()防止页面缓存导致验证码不变
function changeCode() {
$("#imgVcode").attr("src", "servlet/getVcode?ts=" + new Date().getTime());
}
定义外部的js user_login.js
文件的内容 如下(注意这里没有<script></script>)
function changeCode() {
$("#imgVcode").attr("src", "servlet/getVcode?ts=" + new Date().getTime());
}
在jsp页面中引入外部js
<head>
<script type="text/javascript" src="js/user_login.js"></script>
</head>
Jquey链式编程
Jquery为单个元素指定事件处理方式
//处理提交按纽图片
$("#submitBtn").mouseover(function(){
this.src = "images/login_submitBtn2.gif";
}).mouseout(function(){
this.src = "images/login_submitBtn1.gif";
}).click(function() {
submitForm();//自定义函数
});
Jquery为多个元素一起指定事件处理方式
$("input[name=account], input[name=passwd], #submitBtn").click(function(){
$("div.validateCodeDiv").css("display", "none");
}).focus(function() {
$("div.validateCodeDiv").css("display", "none");
});
Jquey获取表单元素的一种方式,使用name 属性
function submitForm() {
var oAcc = $("input[name=account]");
if(oAcc.val().trim().length == 0) {
$("#messBox").html("请输入用户名");
oAcc.focus();
return;
}
var oPass = $("input[name=passwd]");
if(oPass.val().trim().length == 0) {
$("#messBox").html("请输入密码");
oPass.focus();
return;
}
var oVcode = $("input[name=vcode]");
if(oVcode.val().trim().length == 0) {
$("#messBox").html("请输入验证码");
oVcode.focus();
return;
}
var url = "userLogin.do";
//自定义表单的数据序列化
//var para = getFormPara($("form[name=frm1]"));
使用jquey的函数获取表单数据的集合
var para = $("form[name=frm1]").serialize();
注意下面要使用$.post,不要使用$.get(会出现中文乱码)
$.post(url, para, function(data) {
if (data == "vcode error") {
$("#messBox").html("验证码错误");
} else if (data == "userpass error") {
$("#messBox").html("用户名或密码错误");
} else {
location = "home.do";
}
changeCode(); //立即再改变验证码
});
}
对注册页面进行修改,测试jquery的serialize()获取表单的数据,
这里用到了
$.post(url, para, function(data) {})
修改后的Jsp的页面截图
使用下面的js代码测试
var para = $("form[name=frm1]").serialize();
alert(para);
弹出的内容转码了,但是在action中显示的还是中文,
可能是在web.xml中配置的字符编码过滤器起了作用
<filter>
<filter-name>CharsetFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharsetFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Java代码,当jquey的$.post方法提交到下面的action时,各属性会使用jquey传过来的参数赋值
public class UserLoginAction implements ServletResponseAware {
private String account;
private String passwd;
private String vcode;
private String sex;
private String address;
private String introduction;
处理ajax的请求的java代码
Struts2的action中获取session
Map<String, Object> session = ActionContext.getContext().getSession();
PrintWriter out = response.getWriter();
//从session中获取验证码
String realVcode = (String) session.get("vcode");
if (!realVcode.equalsIgnoreCase(vcode)) {
out.print("vcode error"); //返回ajax的请求的数据
out.close();
return null; //返回null,不指定result
}
if (!userLoginService.validateUser(account, passwd)) {
out.print("userpass error");
out.close();
return null; //返回null,不指定result
}
//将用户信息放入SESSION
session.remove("vcode");
session.put("loginUser", "张三");
session.put("skin", "default");
out.print("success");
out.close();
return null; //返回null,不指定result
}
断点跟踪java代码,中文也正确的显示
经过测试发现,<input>标签中的text radio,以及<select> 、<textarea>使用serialize()方法,都会正确的获取表单的结合
js获得元素的绝对位置
function getAbsPosition(o){
把传进来的对象,(不论是dom对象还是jquey对象都可以)转为jquey对象
o = $(o);
if (o.length == 0) {
return false;
}
再重新转换为dom对象
o = o[0];
var left, top;
left = o.offsetLeft;
top = o.offsetTop;
while (o = o.offsetParent) {
left += o.offsetLeft;
top += o.offsetTop;
}
return {
left: left,
top: top
};
}
自定义js的函数
String.prototype.trim = function(){
return this.replace(/(^\s*)|(\s*$)/g, "");
};
String.prototype.startWith = function(str){
if (typeof(str) === "undefined") {
return false;
}
str = str.toString();
if (this.substr(0, str.length) == str) {
return true;
} else {
return false;
}
}
String.prototype.endWith = function(otherStr){
if (typeof(otherStr) === "undefined") {
return false;
}
otherStr = otherStr.toString();
var startPos = this.length - otherStr.length;
if (startPos >= 0) {
var tmp = this.substr(startPos);
if (tmp === otherStr) {
return true;
} else {
return false;
}
} else {
return false;
}
}
String.prototype.contains = function(otherStr){
if (typeof(otherStr) === "undefined") {
return false;
}
if (this.indexOf(otherStr.toString()) == -1) {
return false;
} else {
return true;
}