• 验证表单重复提交(防止钓鱼,密码加密,自定义标签,过滤器)


    这是本工程所有包与类。

    1.创建好登录、注册页面。

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ taglib uri="http://www.chinasofti.com/token" prefix="csi" %>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'regist.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
    
      </head>
      
      <body>
        <form action="regist" method="post">
            此处用到自定义标签
            <csi:token/>
            用户名:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            <input type="submit" value="注册">
        </form>
      </body>
    </html>
        
    <body>
        <form action="login" method="post">
            用户名:<input type="text" name="username" value="${user }"><br>
            密码:<input type="password" name="password"><br>
            <input type="submit" value="登录">
        </form>
      </body>
    
    这里是登录界面,主体内容

    2.创建登录、注册的servlet类

    package com.chinasofti.um.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import com.chinasofti.common.service.DomainProtectedService;
    import com.chinasofti.util.sec.Passport;
    
    public class LoginServlet extends HttpServlet {
    
        
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            doPost(request, response);
        }
    
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            response.setContentType("text/html;charset=utf-8");
            request.setCharacterEncoding("utf-8");
            PrintWriter out = response.getWriter();
    
            Passport passport = new Passport();
            
    
            DomainProtectedService dps = new DomainProtectedService();
            if (dps.isFromSameDomain()) {
                String username = request.getParameter("username");
                String password = passport.md5(request.getParameter("password"));
                
                HttpSession session = request.getSession();
                session.setAttribute("user", username);
                
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    Connection conn = DriverManager.getConnection(
                            "jdbc:mysql://localhost:3306/ordersys", "root", "1");
    
                    PreparedStatement pstmt = conn
                            .prepareStatement("select * from user_info where username=?");
                    pstmt.setString(1, username);
                    ResultSet rs = pstmt.executeQuery();
                    if (rs.next()) {
                        String passdb = rs.getString(3);
                        if (passdb.equals(password)) {
                            out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
                            out.println("<HTML>");
                            out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
                            out.println("  <BODY>");
                            out.println("登录成功!");
                            out.println("  </BODY>");
                            out.println("</HTML>");
                        } else {
                            out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
                            out.println("<HTML>");
                            out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
                            out.println("  <BODY>");
                            out.println("密码错误!");
                            out.println("  </BODY>");
                            out.println("</HTML>");
                        }
                    } else {
                        out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
                        out.println("<HTML>");
                        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
                        out.println("  <BODY>");
                        out.println("用户名错误!");
                        out.println("  </BODY>");
                        out.println("</HTML>");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else{
                out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
                out.println("<HTML>");
                out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
                out.println("  <BODY>");
                out.println("非法登录!");
                out.println("  </BODY>");
                out.println("</HTML>");
            }
    
            out.flush();
            out.close();
        }
    
    }
    package com.chinasofti.um.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.util.UUID;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.chinasofti.um.common.taglib.TokenTag;
    import com.chinasofti.util.sec.Passport;
    
    public class RegistServlet extends HttpServlet {
    
        
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            doPost(request, response);
        }
    
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            response.setContentType("text/html;charset=utf-8");
            request.setCharacterEncoding("utf-8");
            PrintWriter out = response.getWriter();
            Passport passport = new Passport();
            
            //判断令牌是否有效
            if(TokenTag.isTokenValid()){
                String username = request.getParameter("username");
                //String password = request.getParameter("password");
                String password = passport.md5(request.getParameter("password"));
                //通过UUID来生产唯一的用户ID,作为主键
                String userID = UUID.randomUUID().toString();
                
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ordersys", "root", "1");
                    
                    PreparedStatement pstmt = conn.prepareStatement("insert into user_info values(?,?,?)");
                    pstmt.setString(1, userID);
                    pstmt.setString(2, username);
                    pstmt.setString(3, password);
                    
                    pstmt.executeUpdate();
                } catch (Exception e) {
                    e.printStackTrace();
                } 
                
                //释放令牌
                TokenTag.releaseToken();
                out.println("注册成功!<br>");
            }else{
                out.println("令牌无效,非法注册!<br>");
            }
        }
    
    }

    3.创建防止表单重复提交的标签

    package com.chinasofti.um.common.taglib;
    
    import java.io.IOException;
    import java.util.UUID;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.TagSupport;
    
    import com.chinasofti.um.common.httprequest.HttpRequestContext;
    /**
     * <p>
     * Title:TokenTag
     * </p>
     * <p>
     * Decription:防止表单重复提交的标签
     * </p>
     * @author csi
     * @version 1.0
     *
     */
    public class TokenTag extends TagSupport {
    
        /**
         * 令牌属性:在session中的属性名
         */
        public static final String TOKEN_SESSION_ATTR_NAME = "SUBMIT_TOKEN_ATTR_NAME_SESSION";
        /**
         * 令牌属性:在request中的属性名
         */
        public static final String TOKEN_REQUEST_ATTR_NAME = "SUBMIT_TOKEN_ATTR_NAME_REQUEST";
        
        /**
         * 判断当前请求中是否包含合法令牌值的方法
         * 
         * @return true-请求中包含合法令牌值,false-请求中不包含合法令牌值
         */
        public static boolean isTokenValid(){
            //获取请求中的令牌值
            String requestToken = HttpRequestContext.getRequest().
                    getParameter(TOKEN_REQUEST_ATTR_NAME);
            //获取会话中的令牌值
            Object sessionToken = HttpRequestContext.getRequest().getSession().
                    getAttribute(TOKEN_SESSION_ATTR_NAME);
        System.out.println(requestToken + "--->" + sessionToken);
            //判断令牌是否合法
            return sessionToken != null && sessionToken.toString().equals(requestToken);
        }
        
        /**
         * 释放会话中令牌值
         */
        public static void releaseToken(){
            HttpRequestContext.getRequest().getSession().
                    setAttribute(TOKEN_SESSION_ATTR_NAME, "");
        }
        
        @Override
        public int doEndTag() throws JspException {
            
            //利用UUID获取唯一的令牌值
            String token = UUID.randomUUID().toString();
            //在会话session中保存令牌值
            pageContext.getSession().setAttribute(TOKEN_SESSION_ATTR_NAME, token);
            //创建表单令牌的HTML字符串
            String tokenTag = "<input type="hidden" name="SUBMIT_TOKEN_ATTR_NAME_REQUEST" value="" + 
                                            token + ""/>";
            try {
                //在页面中输出令牌域字符串
                pageContext.getOut().print(tokenTag);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //本标签结束后继续执行页面的其他内容
            return EVAL_PAGE;
        }
    
        @Override
        public int doStartTag() throws JspException {
            //跳过标签体
            return SKIP_BODY;
        }
    
        
    }

    4.创建过滤器(在处理每次请求前捕获请求,响应对象的过滤器)

    package com.chinasofti.um.common.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.chinasofti.um.common.httprequest.HttpRequestContext;
    /**
     * 在处理每次请求前捕获请求,响应对象的过滤器
     * @author csi
     * @version 1.0
     *
     */
    public class HttpRequestContextFilter implements Filter {
    
        private ServletContext context;
        
        @Override
        public void destroy() {
            
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            //在ThreadLocal中共享本次请求、响应对象
            HttpRequestContext.setHttpRequestContext((HttpServletRequest)request, 
                    (HttpServletResponse)response, context);
            
            chain.doFilter(request, response);
        }
    
        @Override
        /**
         * 过滤器初始化是执行的回调方法
         * @param config
         *             过滤器配置对象,可以读取配置文件中的特殊的配置信息
         */
        public void init(FilterConfig config) throws ServletException {
            //使用过滤器配置对象获取ServletContext对象
            context = config.getServletContext();    
    
        }
    
    }

    5.创建  请求,响应,ServletContext对象的包装对象

    package com.chinasofti.um.common.httprequest;
    
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 请求,响应,ServletContext对象的包装对象
     * @author csi
     * @version 1.0
     *
     */
    public class HttpRequestContext {
    
        /**
         * 请求对象
         */
        private HttpServletRequest request;
        /**
         * 响应对象
         */
        private HttpServletResponse response;
        /**
         * ServletContext对象
         */
        private ServletContext servletContext;
        /**
         * 构造器,构造包装对象
         * @param request
         *             请求对象
         * @param response
         *             响应对象
         * @param servletContext
         *             Servlet上下文对象
         */
        public HttpRequestContext(HttpServletRequest request,HttpServletResponse response,
                ServletContext servletContext){
            //初始化request对象
            this.request = request;
            //初始化response对象
            this.response = response;
            //初始化ServletContext对象
            this.servletContext = servletContext;
        }
        
        /**
         * ThreadLocal对象,用于在单一线程中共享数据
         */
        private static ThreadLocal<HttpRequestContext> currentContext = new ThreadLocal<HttpRequestContext>();
        
        /**
         * 设置共享数据的方法
         * @param request  请求对象
         * @param response 响应对象
         * @param servletContext ServletContext对象
         */
        public static void setHttpRequestContext(HttpServletRequest request,HttpServletResponse response,
                ServletContext servletContext){
            //构造包装对象
            HttpRequestContext context = new HttpRequestContext(request, response, servletContext);
            //在ThreadLocal中存放包装对象
            currentContext.set(context);
        }
    
        /**
         * 获取请求对象
         * @return 请求对象
         */
        public static HttpServletRequest getRequest() {
            return currentContext.get() == null ? null 
                    : currentContext.get().request; 
        
        }
    
        /**
         * 获取响应对象
         * @return 响应对象
         */
        public static HttpServletResponse getResponse() {
            return currentContext.get() == null ? null 
                    : currentContext.get().response; 
        }
    
        /**
         * 获取ServletContext对象
         * @return ServletContext对象
         */
        public static ServletContext getServletContext() {
            return currentContext.get() == null ? null 
                    : currentContext.get().servletContext; 
        }
    }

    6.创建 防止盗链、防止外站提交数据的服务对象

    /**
     *  Copyright 2015 ChinaSoft International Ltd. All rights reserved.
     */
    package com.chinasofti.common.service;
    
    import javax.servlet.http.HttpServletRequest;
    
    import com.chinasofti.um.common.httprequest.HttpRequestContext;
    
    /**
     * <p>
     * Title: DomainProtectedService
     * </p>
     * <p>
     * Description: 防止盗链、防止外站提交数据的服务对象
     * </p>
     * <p>
     * Copyright: Copyright (c) 2015
     * </p>
     * <p>
     * Company: ChinaSoft International Ltd.
     * </p>
     * 
     * @author etc
     * @version 1.0
     */
    public class DomainProtectedService {
    
        /**
         * 判定是否盗链或是否外站提交数据的方法
         * 
         * @return 判定结果,ture表示本站合法请求,false表示外站请求
         * */
        public boolean isFromSameDomain() {
            // 获取本次的请求对象
            HttpServletRequest request = HttpRequestContext.getRequest();
            // 获取本站的context root
            String path = request.getContextPath();
            // 获取本站截至到context root的域名信息
            String basePath = request.getScheme() + "://" + request.getServerName()
                    + ":" + request.getServerPort() + path + "/";
            // 获取上一个页面的地址
            String fromUrl = request.getHeader("referer");
    
            System.out.println(fromUrl + "--->" + basePath);
    
            // 判定是否外站请求并返回结果
            return fromUrl != null && fromUrl.startsWith(basePath) ? true : false;
    
        }
    
    }

    7.创建一个算法对密码进行加密

    包含几种加密方法
    package com.chinasofti.util.sec;
    
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Random;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    /**
     * <p>
     * Title: Passport
     * </p>
     * <p>
     * Description:自定义的可逆加密算法,主要用于非超大容量的字符串加密,可以生成网络传输数据的令牌,不同时间执行加密算法获取到的加密结果不同
     * </p>
     * <p>
     * Copyright: Copyright (c) 2015
     * </p>
     * <p>
     * Company: ChinaSoft International Ltd.
     * </p>
     * 
     * @author etc
     * @version 1.0
     */
    public class Passport {
    
        public Passport() {
            // TODO 自动生成构造函数存根
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO 自动生成方法存根
            Passport passport = new Passport();
            // String txt = "中文文本";
            // String key = "chinasofti";
            // String jia_str = passport.passport_encrypt(txt, key);
            // String jie_str = passport.passport_decrypt(jia_str, key);
            // System.out.println("加密函数测试:" + jia_str);
            // System.out.println("解密函数测试:" + jie_str);
    
            System.out.println(passport.md5("admin"));
    
        }
    
        /**
         * Md5加密
         * 
         * @param x
         *            需要加密的字符串
         * @return md5加密结果
         * @throws Exception
         */
        public String md5(String x) {
            // 获取摘要工具
            MessageDigest m = null;
            try {
                // MD5摘要工具
                m = MessageDigest.getInstance("MD5");
                // 更新被文搞描述的位元组
                m.update(x.getBytes("UTF8"));
                // 捕获不支持摘要异常
            } catch (NoSuchAlgorithmException e) {
                // 创建一个MD5消息文搞 的时候出错
                e.printStackTrace();
                // 捕获不支持字符集异常
            } catch (UnsupportedEncodingException e) {
                // 更新被文搞描述的位元组 的时候出错
                e.printStackTrace();
            }
            // 最后更新使用位元组的被叙述的排列,然后完成文摘计算
            byte s[] = m.digest();
            // System.out.println(s); // 输出加密后的位元组
            // 创建结果字符串缓冲
            StringBuilder result = new StringBuilder("");
            // 遍历文摘
            for (int i = 0; i < s.length; i++) {
                // 进行十六进制转换
                result.append(Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00)
                        .substring(6));
            }
            // 返回加密结果
            return result.toString();
    
        }
    
        /**
         * 本方法将字符串以 MIME BASE64 编码。此编码方式可以让中文字或者图片也能在网络上顺利传输。在 BASE64
         * 编码后的字符串只包含英文字母大小写、阿拉伯数字、加号与反斜线,共 64 个基本字符,不包含其它特殊的字符, 因而才取名
         * BASE64。编码后的字符串比原来的字符串长度再加 1/3 左右。更多的 BASE64 编码信息可以参考 RFC2045 文件之 6.8 节
         * 
         * @param txt
         *            等待编码的原字串
         * @return 编码后的结果
         */
        public String base64_decode(String txt) {
            // 定义编码器
            BASE64Decoder base64_decode = new BASE64Decoder();
            // 定义结果字符串
            String str = "";
            try {
                // 获取加密结果
                str = new String(base64_decode.decodeBuffer(txt));
            } catch (IOException e) {
                // 如果有异常则输出异常信息
                e.printStackTrace();
            }
            // 返回编码结果
            return str;
        }
    
        /**
         * Base64编码的方法
         * 
         * @param txt
         *            要编码的字符串
         * @return 编码结果
         * */
        public String base64_encode(String txt) {
            // 创建编码器
            BASE64Encoder base64_encode = new BASE64Encoder();
            // 返回编码结果
            return base64_encode.encode(txt.getBytes());
        }
    
        /**
         * Passport 加密方法
         * 
         * @param string
         *            等待加密的原字串
         * @param string
         *            私有密匙(用于解密和加密)
         * 
         * @return string 原字串经过私有密匙加密后的结果
         */
        public String passport_encrypt(String txt, String key) {
            // 创建随机工具
            Random random = new Random();
            // 使用随机数发生器产生 0~32000 的值
            String rad = String.valueOf(random.nextInt(32000));
            // 获取随机值的md5码
            String encrypt_key = md5(rad);
    
            // 变量初始化
            int ctr = 0;
            // 定义结果字符串缓冲
            StringBuilder tmp = new StringBuilder("");
    
            // 获取md5码的字符数组形式
            char encrypt_key_char[] = encrypt_key.toCharArray();
            // 获取初始文本的字符数组形式
            char txt_char[] = txt.toCharArray();
            // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
            for (int i = 0; i < txt.length(); i++) {
                // 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
                ctr = ctr == encrypt_key_char.length ? 0 : ctr;
                // $tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位,
                // 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1
                char tmp1 = txt_char[i];
                // 编码字符
                char tmp4 = encrypt_key_char[ctr];
                // 编码第二个字符
                char tmp2 = encrypt_key_char[ctr++];
                // 进行位运算
                char tmp3 = (char) (tmp1 ^ tmp2);
                // 添加结果数据
                tmp.append(tmp4 + "" + tmp3);
            }
            // 返回结果,结果为 passport_key() 函数返回值的 base65 编码结果
            return base64_encode(passport_key(tmp.toString(), key));
    
        }
    
        /**
         * Passport 解密方法
         * 
         * @param string
         *            加密后的字串
         * @param string
         *            私有密匙(用于解密和加密)
         * 
         * @return string 字串经过私有密匙解密后的结果
         */
        public String passport_decrypt(String txt, String key) {
    
            // $txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起,
            // 经过 passport_key() 函数处理后的返回值
            txt = passport_key(base64_decode(txt), key);
            // 变量初始化
            StringBuilder tmp = new StringBuilder("");
            // 获取字符串数组形式
            char txt_char[] = txt.toCharArray();
            // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
            for (int i = 0; i < txt.length(); i++) {
                // $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
                // 与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1
                tmp.append((char) (txt_char[i] ^ txt_char[++i]));
            }
    
            // 返回 $tmp 的值作为结果
            return tmp.toString();
    
        }
    
        /**
         * Passport 密匙处理方法
         * 
         * @param string
         *            待加密或待解密的字串
         * @param string
         *            私有密匙(用于解密和加密)
         * 
         * @return string 处理后的密匙
         */
        String passport_key(String txt, String encrypt_key) {
    
            // 将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值
            encrypt_key = md5(encrypt_key);
            // 变量初始化
            int ctr = 0;
            // 创建结果字符串缓冲
            StringBuilder tmp = new StringBuilder("");
    
            // 获取md5码字符数组形式
            char encrypt_key_char[] = encrypt_key.toCharArray();
            // 获取原文本字符数组表现形式
            char txt_char[] = txt.toCharArray();
            // for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
            for (int i = 0; i < txt.length(); i++) {
                // 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
                ctr = ctr == encrypt_key.length() ? 0 : ctr;
                // $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
                // 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1
                char c = (char) (txt_char[i] ^ encrypt_key_char[ctr++]);
                // 追加结果
                tmp.append(c);
            }
    
            // 返回 $tmp 的值作为结果
            return tmp.toString();
    
        }
    
    }

    8.配置xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      <display-name></display-name>
      
      <filter>
          <filter-name>httpRequestContext</filter-name>
          <filter-class>com.chinasofti.um.common.filter.HttpRequestContextFilter</filter-class>
      </filter>
      
      <filter-mapping>
          <filter-name>httpRequestContext</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
      
      <servlet>
        <servlet-name>RegistServlet</servlet-name>
        <servlet-class>com.chinasofti.um.servlet.RegistServlet</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.chinasofti.um.servlet.LoginServlet</servlet-class>
      </servlet>
    
    
      <servlet-mapping>
        <servlet-name>RegistServlet</servlet-name>
        <url-pattern>/regist</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
      </servlet-mapping>    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>

    9.配置自定义标签的.tld文件

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <taglib xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
        version="2.1">
      <description>csi 1.0 token library</description>
      <display-name>token core</display-name>
      <tlib-version>1.2</tlib-version>
      <short-name>csi</short-name>
      <uri>http://www.chinasofti.com/token</uri>
      
      <tag>
          <name>token</name>
          <tag-class>com.chinasofti.um.common.taglib.TokenTag</tag-class>
          <body-content>empty</body-content>
      </tag>
    </taglib>

    10.此处用到了数据库,我们将数据库的jar包放到lib文件下,配置好这几个文件,就ok了,

    验证表单重复提交(防止钓鱼,密码加密,自定义标签,过滤器)等,

  • 相关阅读:
    (转)ASP.NET Mvc 2.0 1. Areas的创建与执行
    新世代交易管理機制~System.Transactions
    水晶報表入門
    MyGeneration 如何连接 mysql 来生成代码
    vs.net 启动不了
    Oracle面试问题-技术篇
    把excel两列字符数据用逗号合并起来
    论Leader的技能
    物流行业名词
    html 向aspx 页面传值
  • 原文地址:https://www.cnblogs.com/lixiaopan/p/6230353.html
Copyright © 2020-2023  润新知