10EasyMall 商城项目1 ---项目搭建、注册页面、验证码

 

1.项目介绍

商城网站:

功能:注册、登录、注销、记住用户名、30天自动自动登录、全站乱码过滤

2.EasyMall环境搭建

  1. 工作环境:window系统、服务器--tomcat、MyEclipse、Mysql
  2. 开发环境:jdk1.6  
  3. 开发内容:

开发一个www.easymall.com网站,并且将其配置为一个缺省的虚拟主机。在其中添加EasyMall web应用,将应用配置为缺省web应用,且配置缺省主页。

  1. 创建虚拟主机---www.easymall.com网站:

在server.xml中添加一个Host标签,内容如下:

 

     

修改server.xml中标签:

 

配置hosts文件 ,添加内容如下:

127.0.0.1 www.easymall.com

创建EasyMall应用

Myeclipse中新建web应用:

发布web应用:

10EasyMall 商城项目1 ---项目搭建、注册页面、验证码_第1张图片

选择custom location 因为我们的www.easymall.com虚拟主机管理的文件是D:www.easymall.com,而不是在tomcat自己中,所以要选择自定义位置。

修改成ROOT是因为想缺省web应用

10EasyMall 商城项目1 ---项目搭建、注册页面、验证码_第2张图片

 10EasyMall 商城项目1 ---项目搭建、注册页面、验证码_第3张图片

 

f.     准备页面

在课前资料中导入首页的三部分:头部、身体和尾部

i.     将以上三个HTML页面转换成jsp页面:

1.    创建与HTML页面对应名称的jsp页面。

2.    复制HTML中的全部内容

3.    粘贴在对应名称的jsp页面中,只保留jsp页面的第一行。(第一行修改字符集为utf-8)

4.    删除所有HTML页面

g.    将头部身体和尾部组合:

一个网站的头部和尾部可能需要频繁使用,如果在每一个网页中单独书写这些内容,十分不便,并且,将来维护修改的时候,工作量很大。所以讲它们抽取成两个单独的页面,在需要的页面中将它们引入。

i.     代码实现:有两种方式

1.是动态引入

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" buffer="0kb"%> //jsp页面的文档说明,buffer="0kb"是设置缓存区大小,默认是8kb。设置0kb的意义是服务器响应的内容可以实时展现到客户端。

<%
request.getRequestDispatcher("/_head.jsp").include(request, response); %> --%>

2.静态导入

    <%@ include file="/_head.jsp" %>

首先是工具类

package com.easymall.utils;
//web工具类
public class WebUtils {
//构造方法私有化
    private WebUtils()
    {
        
    }
    //非空校验
    public static boolean isNull(String name)
    {
        return (name==null)||"".equals(name);
    }

}
package com.easymall.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

//Jdbc的工具类
public class JDBCUtils {
    //创建数据源,只完成一次初始化
    private    static ComboPooledDataSource source= new ComboPooledDataSource();
    //获取数据源
    public    static ComboPooledDataSource getSource(){
        return source;
    }
    //私有化构造方法
    private JDBCUtils(){

    }
    //获取连接
    public static Connection getConnection() throws SQLException{
        return source.getConnection();
    }
    //关闭资源
    public static void close(Connection conn,Statement stat,ResultSet rs)
    {
           if(rs !=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }finally{
                    rs = null;
                }
            }
            if(stat != null){
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }finally{
                    stat = null;
                }
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }finally{
                    conn = null;
                }
            }
            
    }
}
ComboPooledDataSou
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/easymall  //easymall是创建的数据库

c3p0.user=root
c3p0.password=root

 

rce的配置文件

接下来是RegistServlet.servlet动态文件的书写,其作用是注册页面通过表单提交post的方式,请求到RegistServlet.servlet的dopost()方法转给doget()方法,在doget中实现 1.注册文本框非空状态的检测 2.密码的一致性 3.邮箱格式4JDBC用连接池技术访问数据库

            package com.easymall.servlet;
            
            import java.io.IOException;
            import java.sql.Connection;
            import java.sql.PreparedStatement;
            import java.sql.ResultSet;
            import java.sql.SQLException;
            
            import javax.servlet.ServletException;
            import javax.servlet.http.HttpServlet;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            
            import com.easymall.utils.JDBCUtils;
            import com.easymall.utils.WebUtils;
            //注册Servlet
            public class RegistServlet extends HttpServlet {
            
                    public void doGet(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                            //1.请求乱码处理
                            request.setCharacterEncoding("utf-8");  //这是设置服务器接收来自浏览器数据的编码格式 这是只适用于请求体中的内容 即post请求  get请求要先将数据转成二进制,然后根据需求的编码转换
                            //响应乱码处理
                            response.setContentType("text/html;charset=utf-8"); //这是设置浏览器端接受数据采用的编码格式 get和post请求都是可以用这个控制
                            //2.请求参数
                            String username = request.getParameter("username");
                            String password = request.getParameter("password");
                            String password2 = request.getParameter("password2");
                            String nickname = request.getParameter("nickname");
                            String email = request.getParameter("email");
                            String valistr = request.getParameter("valistr"); //验证码的
                            //3.非空校验
                            if(WebUtils.isNull(username)){  
                                    //将错误提示放入request域
                                    request.setAttribute("msg", "用户名不能为空");
                                    //使用请求转发,将request转发到regist.jsp页面
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    //请求转发前后的代码会正常执行,应该在发生校验时打断代码。
                                    return;
                            }
                            if(WebUtils.isNull(password)){
                                    //将错误提示放入request域
                                    request.setAttribute("msg", "密码不能为空");
                                    //使用请求转发,将request转发到regist.jsp页面
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    //请求转发前后的代码会正常执行,应该在发生校验时打断代码。
                                    return;
                            }
                            if(WebUtils.isNull(password2)){
                                    //将错误提示放入request域
                                    request.setAttribute("msg", "确认密码不能为空");
                                    //使用请求转发,将request转发到regist.jsp页面
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    //请求转发前后的代码会正常执行,应该在发生校验时打断代码。
                                    return;
                            }
                            if(WebUtils.isNull(nickname)){
                                    //将错误提示放入request域
                                    request.setAttribute("msg", "昵称不能为空");
                                    //使用请求转发,将request转发到regist.jsp页面
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    //请求转发前后的代码会正常执行,应该在发生校验时打断代码。
                                    return;
                            }
                            if(WebUtils.isNull(email)){
                                    //将错误提示放入request域
                                    request.setAttribute("msg", "邮箱不能为空");
                                    //使用请求转发,将request转发到regist.jsp页面
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    //请求转发前后的代码会正常执行,应该在发生校验时打断代码。
                                    return;
                            }
                            if(WebUtils.isNull(valistr)){
                                    //将错误提示放入request域
                                    request.setAttribute("msg", "验证码不能为空");
                                    //使用请求转发,将request转发到regist.jsp页面
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    //请求转发前后的代码会正常执行,应该在发生校验时打断代码。
                                    return;
                            }
                            //4.密码一致性校验
                            if(password!= null&&password2!=null&&!password.equals(password2)){
                                    request.setAttribute("msg", "两次密码不一致");
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    return;
                            }
                            //5.邮箱格式校验
                            //[email protected]
                            String reg = "\\w+@\\w+(\\.\\w+)+";
                            if(email!= null&&!email.matches(reg)){
                                    request.setAttribute("msg", "邮箱格式不正确");
                                    request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                    return;
                            }
                            //6.验证码校验
                                    //TODO:session
                            //7.完成注册
                            //JDBC   jar
                            //用户名是否存在校验
                            
                            Connection conn = null;
                            PreparedStatement ps = null;
                            ResultSet rs = null;
                            try {
                                    conn = JDBCUtils.getConnection();
                                    ps = conn.prepareStatement("select * from user where username=?");
                                    ps.setString(1, username);
                                    rs = ps.executeQuery();
                                    if(rs.next()){
     //用户名已存在,在页面中作出提示
                                            request.setAttribute("msg", "用户名已存在");
                                            request.getRequestDispatcher("/regist.jsp").forward(request, response);
                                            return;
                                    }else{
     //用户名不存在,可以完成注册
                                            conn = JDBCUtils.getConnection();
                                            ps = conn.prepareStatement("insert into user values(null,?,?,?,?)");
                                            ps.setString(1, username);
                                            ps.setString(2, password);
                                            ps.setString(3, nickname);
                                            ps.setString(4, email);
                                            ps.executeUpdate();
                                    }
                            } catch (SQLException e1) {
                                    e1.printStackTrace();
                            }finally{
                                    JDBCUtils.close(conn, ps, rs);
                            }
                           
                            //连接池
                            //8.跳转回首页
                            response.getWriter().write("

恭喜注册成功,3秒后跳转回首页

"); response.setHeader("refresh", "3;url=http://www.easymall.com"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

              f. 修改regist.jsp页面,添加代码如下

                     下方的三元表达式,是为了在用户第一次访问的时候不出现null,并且出现错误提示的时候能正常显示

<table>
    <tr>
        <td class="tds" colspan="2"
        style="color:red;text-align:center"
        ><%=request.getAttribute("msg")==null?"":request.getAttribute("msg") %>td>  //获取request域对象中的msg这个域属性,如果有就是注册有不对的地方,在对应的span输出出错内容,如果为null就是没错的
这时候需要将span中的内容设置为空字符串
tr>

  用户信息回显

用户某些信息已经确认,在提交之后,如果页面返回错误提示信息,应该讲部分内容回显,便于用户重新修改。就是方便用户体验

修改regist.jsp页面                <td>                        

                        <input type="text" name="username" 
                        value="<%=request.getParameter("username")==null?"":request.getParameter("username")%>"/> //从request请求中获得需要的上一次的请求参数,用于用户回显上一次数据,
如果第一次点击进来,那么
参数值为null,那么回显的内容就是""

td> <tr> <td class="tds">昵称:td> <td> <input type="text" name="nickname" value="<%=request.getParameter("nickname")==null?"":request.getParameter("nickname")%>"/> td> tr> <tr> <td class="tds">邮箱:td> <td> <input type="text" name="email" value="<%=request.getParameter("email")==null?"":request.getParameter("email")%>"/> td> tr>

添加前台页面的校验

       1. 添加前台页面校验的意义

            如果只作出后台校验,可以防止无效数据入库,但是仍然不能降低服务器的访问压力,所以如果出现不合理的提交数据,应该在前台页面就完成拦截。如此才能降低服务器的访问压力

 

可以通过js来完成页面拦截的效果。

       2. 在页面中添加js校验

 

              a. 修改form表单,添加onsubmit属性

<form action="<%=request.getContextPath() %>/RegistServlet" method="POST" onsubmit="return formObj.checkForm()">  onsubmit是form表单中的一个属性 =true是就是表单提交的时候回跳转,=false时就是表单
不会跳转到action中指定的页面。 checkForm()是一个方法。它可以校验表单的内容是否符合要求,符合返回true,反之为false

              b. 在所有input框后添加span框。

<input type="text" name="username" 
    value="<%=request.getParameter("username")==null?"":request.getParameter("username")%>"/>
<span>span>   //这个span的作用是跟在input后面用于存放错误信息的框

       c.添加js代码

            var formObj = {
                    "checkForm":function(){
                            var canSub = true;
                            //1.获取参数
                            //2.作出校验
                            //非空校验
                            /* var username = $("input[name='username']").val();
                            //清空操作
                            $("input[name='username']").nextAll("span").text("");
                            if(username == ""){
                                    $("input[name='username']").nextAll("span").text("用户名不能为空").css("color","red");
                            } */
                            canSub = this.checkNull("username", "用户名不能为空") && canSub;
                            canSub = this.checkNull("password", "密码不能为空") && canSub;
                            canSub = this.checkNull("password2", "确认密码不能为空") && canSub;
                            canSub = this.checkNull("nickname", "昵称不能为空") && canSub;
                            canSub = this.checkNull("email", "邮箱不能为空") && canSub;
                            canSub = this.checkNull("valistr", "验证码不能为空") && canSub;
                            //密码一致性校验
                            canSub = this.checkPassword() && canSub;
                            //邮箱格式校验
                            canSub = this.checkEmail() && canSub;
                            return canSub;
                    },
                    "checkNull":function(name,msg){
                            //非空校验
                            var tag = $("input[name='"+name+"']").val();
                            //清空操作
                            //$("input[name='"+name+"']").nextAll("span").text("");
                            this.setMsg(name, "");
                            if(tag == ""){
                                    //$("input[name='"+name+"']").nextAll("span").text(msg).css("color","red");
                                    this.setMsg(name, msg);
                                    return false;
                            }
                            return true;
                    },
                    "checkPassword":function(){
                            //密码一致性校验
                            var password = $("input[name='password']").val();
                            var password2 = $("input[name='password2']").val();
                            if(password!="" && password2!="" && password!=password2){
                                    this.setMsg("password2", "两次密码不一致");
                                    return false;
                            }
                            return true;
                    },
                    "checkEmail":function(){
                            //[email protected]
                            var reg = /\w+@\w+(\.\w+)+/;
                            var email = $("input[name='email']").val();
                            if(email!="" && !reg.test(email)){
                                    this.setMsg("email", "邮箱格式不正确");
                                    return false;
                            }
                            return true;
                    },
                    "setMsg":function(name,msg){
                            //消息提示 span
                            $("input[name='"+name+"']").nextAll("span").text(msg).css("color","red");
                    }
                    
                    };

 

 

              d. 前台已经做出校验,后台为何仍需校验?

                     前台页面中的校验只是为了减少无效请求的做出的拦截效果,是使用js代码来实现的。并不能够真正防止无效数据信息加入数据库。而后台java代码当前做出的校验,才是在得到数据之后,真正的校验操作,在判断数据无效之后,可以防止无效数据入库。

 

e.添加离焦事件

//文档就绪事件
    $(function(){
    //为username输入框添加鼠标离焦事件
        $("input[name='username']").blur(function(){
            formObj.checkNull("username", "用户名不能为空");
        });
        $("input[name='password']").blur(function(){
            formObj.checkNull("password", "密码不能为空");
        });
        $("input[name='password2']").blur(function(){
            formObj.checkNull("password2", "确认密码不能为空");
            formObj.checkPassword();
        });
        $("input[name='nickname']").blur(function(){
            formObj.checkNull("nickname", "昵称不能为空");
        });
        $("input[name='email']").blur(function(){
            formObj.checkNull("email", "邮箱不能为空");
            formObj.checkEmail();
        });
        $("input[name='valistr']").blur(function(){
            formObj.checkNull("valistr", "验证码不能为空");
});

添加ajax的用户名是否存在检测----实现局部刷新

编辑region.jsp文件

 

$("input[name='username']").blur(function(){ //离焦事件
formObj.checkNull("username", "用户名不为空");
//获取输入框中的值
var username=$("input[name=username]").val();
//ajax校验用户名是否存在
if(username!="")
$("#username_img").load("<%=request.getContextPath() %>/AjaxCheckUsernameServlet",{"username":username});
});


 

 

创建AjaxCheckUsernameServlet, 处理请求

package com.easymall.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.easymall.utils.JDBCUtils;
//ajax请求,查询数据库中用户名是否存在
public class AjaxCheckUsernameServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.乱码处理
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //2.获取请求参数
        String username=request.getParameter("username");
       //3.访问数据查询用户名是否存在
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            conn=JDBCUtils.getConnection();
            ps=conn.prepareStatement("select * from user where username = ?");
            ps.setString(1, username);
            rs=ps.executeQuery();
            if(rs.next()){
     //如果用户名存在,提示用户更该用户名
                //做出响应
                response.getWriter().write("用户名已存在");
            }else {
                response.getWriter().write("用户名可以使用");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally
        {
            JDBCUtils.close(conn, ps, rs);
        }
        
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);

    }

}

 

修改EasyMall页面中的资源路径

    1. 修改页面中的资源路径

       a. 页面中的静态资源都是相对路径,在使用请求转发访问这些资源的时候,可能会导致路径加载错误。为了避免这个错误,可以在每一个静态资源路径之前拼接上web应用的虚拟路径。这样在静态资源加载的时候,就不会出现路径问题。

       b. 不出现路径问题原因:

           在静态资源之前拼接上web应用的虚拟路径,某些资源发生跳转时,替换的资源路径就会变为从web应用的路径级别开始替换。只要保证这一点,从web应用路径级别设置的静态资源路径就不会出错。

       c. 修改方式:

           各个页面中的静态资源之前,添加如下内容:

           <%=request.getContextPath() %>/

添加验证码图片

1. 引入课前资料中的VerfiyCode

package com.easymall.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
/**
 * 动态生成图片
 */
public class VerifyCode {
    // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
    private static String[] fontNames = { "宋体", "华文楷体", "黑体", "微软雅黑",  "楷体_GB2312" };
    // 可选字符
    //"23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
    private static String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
    // 背景色
    private Color bgColor = new Color(255, 255, 255);
    // 基数(一个文字所占的空间大小)
    private int base = 30;
    // 图像宽度
    private int width = base * 4;
    // 图像高度
    private int height = base;
    // 文字个数
    private int len = 4;
    // 设置字体大小
    private int fontSize = 22;
    // 验证码上的文本
    private String text;

    private BufferedImage img = null;
    private Graphics2D g2 = null;

    /**
     * 生成验证码图片
     */
    public void drawImage(OutputStream outputStream) {
        // 1.创建图片缓冲区对象, 并设置宽高和图像类型
        img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 2.得到绘制环境
        g2 = (Graphics2D) img.getGraphics();
        // 3.开始画图
        // 设置背景色
        g2.setColor(bgColor);
        g2.fillRect(0, 0, width, height);

        StringBuffer sb = new StringBuffer();// 用来装载验证码上的文本

        for (int i = 0; i < len; i++) {
            // 设置画笔颜色 -- 随机
            // g2.setColor(new Color(255, 0, 0));
            g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150),getRandom(0, 150)));

            // 设置字体
            g2.setFont(new Font(fontNames[getRandom(0, fontNames.length)], Font.BOLD, fontSize));

            // 旋转文字(-45~+45)
            int theta = getRandom(-45, 45);
            g2.rotate(theta * Math.PI / 180, 7 + i * base, height - 8);

            // 写字
            String code = codes.charAt(getRandom(0, codes.length())) + "";
            g2.drawString(code, 7 + i * base, height - 8);
            sb.append(code);
            g2.rotate(-theta * Math.PI / 180, 7 + i * base, height - 8);
        }

        this.text = sb.toString();

        // 画干扰线
        for (int i = 0; i < len + 2; i++) {
            // 设置画笔颜色 -- 随机
            // g2.setColor(new Color(255, 0, 0));
            g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150),
                    getRandom(0, 150)));
            g2.drawLine(getRandom(0, 120), getRandom(0, 30), getRandom(0, 120),
                    getRandom(0, 30));
        }
        // 4.保存图片到指定的输出流
        try {
             ImageIO.write(this.img, "JPEG", outputStream);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            // 5.释放资源
            g2.dispose();
        }
    }
    
    /**
     * 获取验证码字符串
     * @return
     */
    public String getCode() {
        return this.text;
    }

    /*
     * 生成随机数的方法
     */
    private static int getRandom(int start, int end) {
        Random random = new Random();
        return random.nextInt(end - start) + start;
    }
    
    public static void main(String[] args) throws Exception {
        VerifyCode vc = new VerifyCode(); 
        vc.drawImage(new FileOutputStream("d:/vc.jpg"));  //指定生成的图片放置的地方
        System.out.println("执行成功~!");
    }
}

我们用这个验证码类 生成验证码图片放置在我么的网上

创建ValidateServlet

    package com.easymall.servlet;
        
        import java.io.FileOutputStream;
        import java.io.IOException;
        
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        
        import com.easymall.utils.VerifyCode;
        //验证码生成的Servlet
        public class ValidateServlet extends HttpServlet {
        
                public void doGet(HttpServletRequest request, HttpServletResponse response)
                        throws ServletException, IOException {
                        //控制浏览器不使用缓存
                        response.setDateHeader("Expires", -1);
                        response.setHeader("Cache-Control", "no-cache");
                        VerifyCode vc = new VerifyCode();
                        //当前servlet只有img标签调用,所以将图片放入缓冲区,
                        //最终会在其调用的位置输出在浏览器中。
                        vc.drawImage(response.getOutputStream());
                        String code = vc.getCode();
                        System.out.println(code);
                        System.out.println("执行成功~!");
                }
        
                public void doPost(HttpServletRequest request, HttpServletResponse response)
                        throws ServletException, IOException {
                        doGet(request, response);
        
                }
        
        }

 

       3. 修改regist.jsp页面

              在文档就绪事件($(function(){}))中添加如下内容:

              //等待页面加载完成后,为验证码图片绑定单击事件,更新验证码 ,实现的效果就是点击验证码图片更新验证码

              

        $("#img").click(function(){

                              var date = new Date();

                              var time = date.getTime();

                              $(this).attr("src","<%=request.getContextPath()%>/ValidateServlet?time="+time); //给这个验证码图片的src属性改成生成验证码图片servlet文件的路径

                      });

 

              a. 添加time参数的原因:

                   因为http协议的设计  浏览器认为每次发送的url地址如果相同,则不需要发送新的请求,为了能够通过单击事件加载新的验证码,需要在url后添加一个变化的参数,保证每一次访问的地址不相同,这样就会发送请求,ValidateServlet创建并返回最新的验证码。

 

修改EasyMall页面中的资源路径

       1. 修改页面中的资源路径

              a. 页面中的静态资源都是相对路径,在使用请求转发访问这些资源的时候,可能会导致路径加载错误。为了避免这个错误,可以在每一个静态资源路径之前拼接上web应用的虚拟路径。这样在静态资源加载的时候,就不会出现路径问题。

              b. 不出现路径问题原因:

                     在静态资源之前拼接上web应用的虚拟路径,某些资源发生跳转时,替换的资源路径就会变为从web应用的路径级别开始替换。只要保证这一点,从web应用路径级别设置的静态资源路径就不会出错。

              c. 修改方式:两种方法

1.删除掉servlet文件的虚拟路径前的/servlet.

              2.    各个页面中的静态资源之前补充上web应用的虚拟路径名称就好,添加如下内容:

                     <%=request.getContextPath() %>/

<link rel="stylesheet" href="<%=request.getContextPath() %>/css/regist.css"/>

 

转载于:https://www.cnblogs.com/xuwangqi/p/11338137.html

你可能感兴趣的:(java,数据库,开发工具)