web项目总结
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; }