这里还是一些老掉牙的问题,CSS,验证码,SSL,Struts Validate等。一个一个记录下来再说:
终于对页面布局有了一点点了解,基本的一个head,一个sidebar,一个mainbody的结构:
/*基本信息*/ body {font:12px Tahoma;margin:0px;text-align:center;background:#FFF;} a:link,a:visited {font-size:12px;text-decoration:none;} a:hover{} /*页面层容器*/ #container {width:700px;margin:10px auto} /*页面头部*/ #header {background:url(../img/logo.gif) no-repeat;height:59px;} #menu {} #menu ul {float:right;list-style:none;margin:0px;width:560px;height:16;background:#EAF3FF} #menu ul li {float:right;display:block;line-height:30px;margin:0 5px} #menu ul li a:link,#menu ul li a:visited {font-weight:bold;font-size:11px;color:#00A3FF} #menu ul li a:hover{} .menuDiv {width:1px;height:28px;background:#CCCCCC;} /*页面主体*/ #pagebody { width:700px; /*设定宽度*/ margin:0px auto; /*居中*/ } #sidebar { background:#F5F8FC; width:320px; /*设定宽度*/ text-align:left; /*文字左对齐*/ float:right; /*浮动居左*/ clear:right; /*不允许左侧存在浮动*/ overflow:hidden; /*超出宽度部分隐藏*/ border:1px solid #78A3D3; height:400px } #sidebar ul {float:right;list-style:none;width:320px;height:16;margin:20px;} #sidebar ul li {font-size:13px;margin:10px;} #sidebar ul li a:link,#sidebar ul li a:visited {font-size:11px;color:#78A3D3} #sidebar ul li a:hover{} .account,.password,.validate { border:1px solid #78A3D3; line-height:100px; width: 120px; height: 20px; } .loginButton { BORDER-RIGHT: #7b9ebd 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #7b9ebd 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 12px; FILTER: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#ffffff, EndColorStr=#cecfde); BORDER-LEFT: #7b9ebd 1px solid; CURSOR: hand; COLOR: black; PADDING-TOP: 2px; BORDER-BOTTOM: #7b9ebd 1px solid } .note { font-size: 11px; color: #868686; } .error { margin:1px 20px; width:120px; color:ff0000; font-size:12; } #mainbody { width:380px; text-align:left; float:left; /*浮动居右*/ clear:left; /*不允许右侧存在浮动*/ overflow:hidden; } #mainbody ul {float:right;list-style:none;width:320px;height:16;margin:20px;} #mainbody ul li {font-size:12px;margin:5px;} /*页面底部*/ #footer {width:800px;margin:0 auto;height:50px;background:#00FFFF}
另外找到一个不错的注册的css:
.css
body { font-family: Arial, Helvetica, sans-serif; font-size:12px; color:#666666; background:#fff; text-align:center; } * { margin:0; padding:0; } a { color:#1E7ACE; text-decoration:none; } a:hover { color:#000; text-decoration:underline; } h3 { font-size:14px; font-weight:bold; } pre,p { color:#1E7ACE; margin:4px; } input, select,textarea { padding:1px; margin:2px; font-size:11px; } .buttom{ padding:1px 10px; font-size:12px; border:1px #1E7ACE solid; background:#D0F0FF; } #formwrapper { width:510px; margin:15px auto; padding:20px; text-align:left; border:1px #1E7ACE solid; } fieldset { padding:10px; margin-top:5px; border:1px solid #1E7ACE; background:#fff; } fieldset legend { color:#1E7ACE; font-weight:bold; padding:3px 20px 3px 20px; border:1px solid #1E7ACE; background:#fff; } fieldset label { float:left; width:120px; text-align:right; padding:4px; margin:1px; } .error { margin:1px 125px; width:120px; color:ff0000; } fieldset div { clear:left; margin-bottom:2px; } .enter{ text-align:center;} .clear { clear:both; }
.jsp
<fieldset> <legend>请选择您的用户名</legend> <div> <label for="username">用户名</label> <input type="text" name="username" id="username" size="20" maxlength="30" onblur="getBackInfo();"/> @ymail.com*<input type="text" id="disCheckResult" size="50" readonly style="border:0;margin:0 80px;font-size=12;color=red"/><br /> <p class="error"><html:errors property="username"/></p> </div> </fieldset> <br /> <fieldset> <legend>请填写相关安全信息</legend> <p><strong>以下信息对保护您的帐户安全十分重要,请谨慎填写并牢记.</strong> 在您注册之前请先认真阅读服务条款.</p> <div> <label for="password">密码</label> <input type="password" name="password" size="18"/> *(至少8个字符)<br /><p class="error"><html:errors property="password"/></p> </div> <div> <label for="password1">重复密码</label> <input type="password" name="password1" size="18"/> *<br /><p class="error"><html:errors property="password1"/></p> </div> <div> <label for="question">密码保护问题</label> <select name="question" class="text" title="密码保护问题"> <option value="" selected="selected">请选择一个问题</option> <option value="我就读的第一所学校的名称?">我就读的第一所学校的名称?</option> <option value="我最喜欢的休闲运动是什么?">我最喜欢的休闲运动是什么?</option> <option value="我最喜欢的运动员是谁?">我最喜欢的运动员是谁?</option> <option value="我最喜欢的物品的名称?">我最喜欢的物品的名称?</option> <option value="我最喜欢的歌曲?">我最喜欢的歌曲?</option> <option value="我最喜欢的食物?">我最喜欢的食物?</option> <option value="我最爱的人的名字?">我最爱的人的名字?</option> <option value="我最爱的电影?">我最爱的电影?</option> <option value="我妈妈的生日?">我妈妈的生日?</option> <option value="我的初恋日期?">我的初恋日期?</option> </select> *<br /><p class="error"><html:errors property="question"/></p> </div> <div> <label for="answer">您的答案</label> <input type="text" name="answer" size="18"/> *<br /><p class="error"><html:errors property="answer"/></p> </div> <div> <label for="nickName">昵称</label> <input type="text" name="nickName" size="18"/> *<br/><p class="error"><html:errors property="nickName"/></p> </div> <div> <label for="sEmail">备用邮箱</label> <input type="text" name="sEmail" value="" size="20" maxlength="150" /> 可以通过备用邮箱来修改您的密码<p class="error"><html:errors property="sEmail"/></p> </div> <div> <label for="agreeToTerms">同意服务条款</label> <input type="checkbox" name="agreeToTerms" value="1" /> <a href="#" title="您是否同意服务条款">先看看条款?</a> * <br/> <p class="error"><html:errors property="agreeToTerms"/></p></div> <div class="enter"> <input name="create791" type="submit" class="buttom" value="提交" /> <input name="Submit" type="reset" class="buttom" value="重置" /> </div> <p><strong>* 在提交您的注册信息时, 我们认为您已经同意了我们的服务条款.<br /> * 这些条款可能在未经您同意的时候进行修改.</strong></p> </fieldset>
可以用js和struts validate,这里两种都用了-_-!!!
先说用框架的:
1.配置文件:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
</plug-in>
2.写验证规则
<form name="registerForm"> <field property="username" depends="required"> <msg name="required" key="error.required"/> <arg0 key="error.username"/> </field> <field property="password" depends="required,minlength"> <msg name="required" key="error.required"/> <arg0 key="error.password"/> <msg name="minlength" key="error.minlength"/> <arg0 key="error.password"/> <arg1 key="${var:minlength}" name="minlength" resource="false"/> <var> <var-name>minlength</var-name> <var-value>8</var-value> </var> </field> <field property="password1" depends="validwhen"> <var> <var-name>test</var-name> <var-value>(password==*this*)</var-value> </var> <msg name="validwhen" key="error.password1"/> </field> <field property="question" depends="required"> <msg name="required" key="error.required"/> <arg0 key="error.question"/> </field> .... </form>
3.写properties文件
4. 别忘了页面上添加<html:errors property="username"/>
本来可以自己写个验证规则来判断用户名是否存在,但是Ajax的无刷新验证看来更具诱惑力,于是对Ajax一窍不通的我做了第一次尝试..貌似也蛮好理解的,即写一个servlet,并用js调用并在页面显示结果。
servlet:
package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ymail.dbimpl.UsersImpl; public class UsernameValidator extends HttpServlet { /** * */ private static final long serialVersionUID = -9038308848332609445L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); // System.out.print("asdfdsaf"); try{ UsersImpl usersImpl = new UsersImpl(); boolean flag = usersImpl.usernameValidate(username); String msg = null; //System.out.print(flag); response.setContentType("text/html;charset=gb2312"); PrintWriter out = response.getWriter(); if (flag) { msg = "用户名"+username+"已经存在"; } else { msg = "恭喜你,"+username+"可以使用"; } out.println(msg); //System.out.print(msg); }catch(Exception ex){ ex.printStackTrace(); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doPost(request, response); } }
js:
<script language="javascript" > var request; /** 下面这个函数可以返回一个适合任何浏览器的httpRequest,步子如下: 1.试着创建一个XMLHttpRequest()示例,该示例可适合于除了微软以外的所有浏览器 2.增加错误判断,如果当前浏览器是微软的,那么就创建适用于微软的浏览器 3.但微软的浏览器又有两个版本之分,不过据说微软已经在7.0中增加对XMLHttpRequest()的支持 4.但这样也需要对原来的浏览器支持,否则你写出来的程序那些用老版本浏览器的用户就是看不 到效果的。 */ function createRequest() { try{ request=new XMLHttpRequest(); }catch(trymicrosoft) { try{ request=new ActiveXObject("Msxml2.XMLHTTP"); }catch(othermicrosoft) { try{ request=new ActiveXObject("Microsoft.XMLHTTP"); } catch(failed) { request=false; } } } if(!request) { alert("err Happend!"); return null; } return request; } /** 这个函数就是用户的动作所有触发的函数,如下面的onblur()时,就会调用该函数 经过的步骤如下: 1.从HTML页面得到你需要的数据,可以采有document.getElementById("")方法。 2.建立需要的URL,该URL就和在FORM里面的method为get时并采用submit提交在地址栏 里面到的一样 3.打开与服务器的连接,这里面有三个必要的参数,虽然文档规定只有两个,但是我个 人觉得最好用三个, 第一个可以是GET,POST或者是POST,但常用的就是前面的两个,并且最好都用大写,因 为有些浏览器如FireFox可能会报错, 第二个就是打报的URL,这肯定你是必须的。 第三个就是下面的看到的true,这里可以是false。true表示同步处理,你提交后可以做 其它的事情,这就是AJAX里面的A,即asynchronous;如是false,那就得等到服务器的返 回才能够做其它的事情。 4.等到服务器完成,并且确定返回执行了正确执行的提示,我们就可以做下面我们想做的 事情。这些后面的事情就必须通过Javascript去完成了,因为XMLHttpRequest的唯一用途 就是发送请求及接收服务器的响应结果。 5.上面都完成了后,就可以采用send()方法向服务器发送你需要发送的信息了,它的参数 可以是任何类型,发送的数据格式必须为这样的格式: name=value&anothername=othervalue&so=on,如果你想传送数据,你必须更改MIME类型: httpRequest.setRequestHeader('Content-type','application/x-www-form-urnlencoded'); 否则服务器将会丢弃发送的数据。 */ function getBackInfo() { request = createRequest(); var username=document.getElementById("username").value; var url='/ymail/usernameValidate?username='+username; // var xmlHttp = new ActiveXObject("MSXML2.XMLHTTP"); //alert("请输入用户名!"); request.open("GET",url,"true"); //下面相当于是一个隐性的循环,在函数中规定只有都接收完毕数据后才做处理 //onreadystatechange有5个值: // 0:未初始化 // 1:初始化 // 2:发送数据 // 3:接收数据中 // 4:数据接收完毕 //另外还要注意就是在注册回调函数onreadystatechange时,后面的函数不能够带参数 //如下disResult是一个函数,不能够带参。 request.onreadystatechange=disResult;//隐性的循环 request.send(null); } function disResult() { /** 1.一定要确定readystate==4的完成状态才做下面的事,否则会在建立连接即readystate==1的 时候就开始,然后会在readystate==2,readystate==3,readystate==4的时候都会执行,不信 你可以alert("")一个提示信息试试。 2.服务器通知完成了,并且还要保证是正确完成的,得到的是我们需要的结果才能够继续,这里 常用响应码有: 200:成功执行 401:未授权 403:禁止 404:没有找到文件 */ if(request.readystate==4) { if(request.status==200) { //一切都OK了,那就该用Javascript去执行你想要的动作了。 document.getElementById("disCheckResult").value=request.responseText; //alert(request.responseText); } else { alert('Something Wrong has Happend!'); } } } </script>
记得在页面中添加错误信息显示的位置:
<input type="text" id="disCheckResult" size="50" readonly style="border:0;margin:0 80px;font-size=12;color=red"/>
怎么也弄不出qq邮箱那个效果,谁能告诉我怎么用java2d画随机曲线的?自己做的比较难看:
package servlet; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * 生成随机验证码 * @author bitiliu * */ public class ValidateCodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; //验证码图片的宽度。 private int width=30; //验证码图片的高度。 private int height=15; //验证码字符个数 private int codeCount=3; private int x=0; //字体高度 private int fontHeight; private int codeY; char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; /** * 初始化验证图片属性 */ public void init() throws ServletException { //从web.xml中获取初始信息 //宽度 String strWidth=this.getInitParameter("width"); //高度 String strHeight=this.getInitParameter("height"); //字符个数 String strCodeCount=this.getInitParameter("codeCount"); //将配置的信息转换成数值 try { if(strWidth!=null && strWidth.length()!=0) { width=Integer.parseInt(strWidth); } if(strHeight!=null && strHeight.length()!=0) { height=Integer.parseInt(strHeight); } if(strCodeCount!=null && strCodeCount.length()!=0) { codeCount=Integer.parseInt(strCodeCount); } } catch(NumberFormatException e) {} x=width/(codeCount+1); fontHeight=height; codeY=height-2; } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException { //定义图像buffer BufferedImage buffImg = new BufferedImage( width, height,BufferedImage.TYPE_INT_RGB); Graphics2D g = buffImg.createGraphics(); //创建一个随机数生成器类 Random random = new Random(); //将图像填充为白色 g.setColor(new Color(230, 243, 255)); g.fillRect(0, 0, width, height); //创建字体,字体的大小应该根据图片的高度来定。 Font font = new Font("Arial", Font.ITALIC, 35); //设置字体。 g.setFont(font); //画边框。 g.setColor(Color.BLACK); g.drawRect(0, 0, width - 1, height - 1); //随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。 g.setColor(Color.BLACK); int red = 0, green = 0, blue = 0; for(int i = 0; i < 20; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(30); int yl = random.nextInt(30); red = random.nextInt(255); green = random.nextInt(255); blue = random.nextInt(255); //用随机产生的颜色将验证码绘制到图像中。 g.setColor(new Color(red, green, blue)); g.setStroke(new BasicStroke(3.0f)); g.drawArc(x, y, xl, yl,random.nextInt(180),random.nextInt(180)); } //randomCode用于保存随机产生的验证码,以便用户登录后进行验证。 StringBuffer randomCode = new StringBuffer(); //随机产生codeCount数字的验证码。 for (int i = 0; i < codeCount; i++) { //得到随机产生的验证码数字。 String strRand = String.valueOf(codeSequence[random.nextInt(36)]); g.setColor(new Color(red, green, blue)); g.drawString(strRand, (i + 1) * x, codeY); //将产生的四个随机数组合在一起。 randomCode.append(strRand); } // 将四位数字的验证码保存到Session中。 HttpSession session = req.getSession(); session.setAttribute("validateCode", randomCode.toString()); // 禁止图像缓存。 resp.setHeader("Pragma", "no-cache"); resp.setHeader("Cache-Control", "no-cache"); resp.setDateHeader("Expires", 0); resp.setContentType("image/jpeg"); //将图像输出到Servlet输出流中。 ServletOutputStream sos = resp.getOutputStream(); ImageIO.write(buffImg, "jpeg", sos); sos.close(); } }
然后再页面插入该servlet:
<img src="/ymail/validateCodeServlet" onclick="refresh(this);"/> <script> function refresh(e){ e.src="validateCodeServlet"; } </script>
提到这个,单向双向是老掉牙的问题,这里不用双向,所以只添加了服务器端的验证:
一、生成 KeyStore
这一步比较简单,利用 JDK 自带的 keytool 即可完成。命令如下:
wakan@wakan:~/tomcat2/bin> keytool -genkey -alias tomcat -keyalg RSA 输入keystore密码: ************ 您的名字与姓氏是什么? [Unknown]: Wakan.Jiang 您的组织单位名称是什么? [Unknown]: ZZNode 您的组织名称是什么? [Unknown]: ZZNode 您所在的城市或区域名称是什么? [Unknown]: BeiJing 您所在的州或省份名称是什么? [Unknown]: BeiJing 该单位的两字母国家代码是什么 [Unknown]: CN CN=Wakan.Jiang, OU=ZZNode, O=ZZNode, L=BeiJing, ST=BeiJing, C=CN 正确吗? [否]: 是 输入<tomcat>的主密码 (如果和 keystore 密码相同,按回车):
特别说明:上边输入的“<tomcat>的主密码”,与keystore密码一定要相同,否则TOMCAT起不来。至少我试了几次都不行。报错如下:
2007-3-26 17:07:01 org.apache.coyote.http11.Http11BaseProtocol init
严重: Error initializing endpoint
java.io.IOException: Cannot recover key
at org.apache.tomcat.util.net.jsse.JSSE14SocketFactory.init(JSSE14Socket Factory.java:125)
二、修改 server.xml
在 TOMCAT/conf/server.xml 中,修改与 SSL 相关的那一段,我改成下面这样:
这里要指定keystorePass,如果写错了,会出现下边的错误:
严重: Error initializing endpoint
java.io.IOException: Keystore was tampered with, or password was incorrect
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:768)
三、启动 Tomcat
这一步比较简单,就不多说了。启动完成后,在浏览器中输入:https://localhost:8443,即可看到TOMCAT的主页面。
<!-- Define a SSL HTTP/1.1 Connector on port 8443 --> <Connector port="8443" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" keystorePass="******" clientAuth="false" sslProtocol="TLS" />