zoukankan      html  css  js  c++  java
  • JDBC整理

    数据库配置文件

    创建 db.properties 资源文件,存放配置信息

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/javaweb?useSSL=true&useUnicode=true&characterEncoding=utf-8
    username=root
    password=123456
    

    操作数据库公共类

    建立 dao 包,然后创建 BaseDao

    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.*;
    import java.util.Properties;
    
    public class BaseDao {
        private static String driver;
        private static String url;
        private static String username;
        private static String password;
        //静态代码块,类加载的时候初始化
        static {
            Properties properties = new Properties();
            //通过类加载器读取对应的资源
            InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
            try {
                properties.load(is);
            } catch (IOException e) {
                e.printStackTrace();
            }
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
        }
        //获取数据库的连接
        public static Connection getConnection(){
            Connection connection = null;
            try {
                Class.forName(driver);
                connection = DriverManager.getConnection(url,username,password);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return connection;
        }
    
        //编写预编译查询公共方法
        public static ResultSet execute(Connection con, PreparedStatement pre, ResultSet rs, String sql, Object[] params) throws SQLException {
           rs=null;
           if(con!=null){
               pre = con.prepareStatement(sql);
               for (int i = 0; i < params.length; i++) {
                   pre.setObject(i+1,params[i]);
               }
               rs = pre.executeQuery();
           }
           return rs;
        }
    
        //编写预编译增删改公共方法
        public static int execute(Connection con, PreparedStatement pre, String sql, Object[] params) throws SQLException {
            int updateRows = 0;
            if(con!=null){
                pre = con.prepareStatement(sql);
                for (int i = 0; i < params.length; i++) {
                    pre.setObject(i+1,params[i]);
                }
                updateRows = pre.executeUpdate();
            }
            return updateRows;
        }
    
        //释放资源
        public static boolean closeResource(Connection con, PreparedStatement pre, ResultSet rs){
            boolean flag = true;
            if(con!=null){
                try{
                    con.close();
                    con = null; //GC回收
                }catch (SQLException e){
                    e.printStackTrace();
                    flag = false;
                }
            }
            if(pre!=null){
                try {
                    pre.close();
                    pre = null;
                } catch (SQLException e) {
                    e.printStackTrace();
                    flag = false;
                }
            }
            if(rs!=null){
                try {
                    rs.close();
                    rs = null;
                } catch (SQLException e) {
                    e.printStackTrace();
                    flag = false;
                }
            }
            return flag;
        }
    }
    

    字符编码过滤器

    建立 filter 包,然后在包下建立CharacterEncodingFilter

    import javax.servlet.*;
    import java.io.IOException;
    public class CharacterEncodingFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {}
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            request.setCharacterEncoding("utf-8");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html; charset=utf-8");
            chain.doFilter(request,response);
        }
    
        @Override
        public void destroy() {}
    }
    

    在 web.xml 下注册编码过滤器,路径根据自己需要更改

    <!-- 字符编码过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.qiu.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    建立实体对象

    建立 pojo 包,然后根据数据库建立对应的实体类

    以user表为例,建立 User 类,根据数据库字段建立对应私有属性,然后建立 get/set 方法,创建有参/无参构造方法

    数据库操作实体类

    建立 user 包,然后建立 UserDao 接口,面向接口编程

    public interface UserDao {
        //得到要登录的用户信息
        public User getLoginUser(Connection con, String username, String password) throws SQLException;
    
        //修改当前用户密码
        public int updatePwd(Connection con, String username, String password)throws SQLException;
    }
    

    编写接口实现类 UserDaoImpl

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class UserDaoImpl implements UserDao {
        //得到要登录的用户
        public User getLoginUser(Connection con, String username, String password) throws SQLException {
            PreparedStatement pre = null;
            ResultSet rs = null;
            User user = null;
            if(con!=null){
                String sql = "select * from user where username=? and password=?";
                Object[] params = {username,password};
                rs = BaseDao.execute(con, pre, rs, sql, params);
                if(rs.next()){
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setUsername(rs.getString("username"));
                    user.setPassword(rs.getString("password"));
                }
                BaseDao.closeResource(null,pre,rs);
            }
            return user;
        }
    
        //修改当前用户密码
        public int updatePwd(Connection con, String username, String password) throws SQLException {
            PreparedStatement pre = null;
            int updateRows = 0;
            if(con!=null){
                String sql = "update user set password = ? where username = ?";
                Object[] params = {password,username};
                updateRows = BaseDao.execute(con, pre, sql, params);
                BaseDao.closeResource(null, pre, null);
            }
            return updateRows;
        }
    }
    

    业务层接口及实现类

    建立 service 包,并在 service 包下建立 user

    然后编写 UserService 接口

    public interface UserService {
        //得到登录信息
        public User login(String username, String password);
    
        //根据用户ID 修改密码
        public boolean updatePwd(String username, String password);
    }
    

    编写接口实现类UserServiceImpl

    public class UserServiceImpl implements UserService {
        //业务层都会调用dao层,所以我们要引入dao层
        private UserDao userDao;
        public UserServiceImpl(){
            userDao = new UserDaoImpl();
        }
    
        @Override
        public User login(String username, String password) {
            Connection con = null;
            User user = null;
            con = BaseDao.getConnection();
            //通过业务层调用对应的具体的数据库操作
            try {
                user = userDao.getLoginUser(con,username,password);
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                BaseDao.closeResource(con,null,null);
            }
            return user;
        }
    
        @Override
        public boolean updatePwd(String username, String password){
            Connection con = null;
            boolean flag = false;
            //根据用户ID 修改密码
            try{
                con = BaseDao.getConnection();
                if(userDao.updatePwd(con, username, password)>0){
                    flag=true;
                }
            }catch (SQLException e){
                e.printStackTrace();
                try {
                    con.rollback();//数据库回滚操作
                } catch (SQLException ex) { ex.printStackTrace(); }
            }finally {
                BaseDao.closeResource(con,null,null);
            }
            return flag;
        }
    }
    

    控制层实现类

    建立 servlet 包,然后建立 user

    在user包下建立 LoginServlet 类来处理登录请求

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class LoginServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //获取用户名和密码
            String username = req.getParameter("username");
            String password = req.getParameter("password");
    
            //和数据库中的账号密码进行对比,调用业务层
            UserService userService = new UserServiceImpl();
            User user = userService.login(username, password);
    
            if(user!=null){
                //将用户信息放到Session中
                req.getSession().setAttribute(Constants.USER_SESSION,user);
                //跳转到主页
                resp.sendRedirect(req.getContextPath()+"/main/success.jsp");
            }else{
                //转发回登录页面,顺带提示它,用户名或者密码错误
                req.setAttribute(Constants.MESSAGE,"用户名或者密码错误");
                req.getRequestDispatcher("/login/login.jsp").forward(req,resp);
            }
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    注册 LoginServlet

    <!--login-->
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.qiu.servlet.user.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>
    

    在user包下建立 UserServlet 类来处理修改密码请求

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class UserServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //从Session里面拿到username
            Object obj = req.getSession().getAttribute(Constants.USER_SESSION);
            String newpassword = req.getParameter("newpassword");
            boolean flag = true;
            if(obj!=null && !StringUtils.isNullOrEmpty(newpassword)){
                UserService userService = new UserServiceImpl();
                flag = userService.updatePwd(((User)obj).getUsername(),newpassword);
                if(flag){
                    req.setAttribute(Constants.MESSAGE,"密码修改成功,请退出重新登录");
                    req.getSession().removeAttribute(Constants.USER_SESSION);
                }else{
                    req.setAttribute(Constants.MESSAGE,"密码修改失败");
                }
            }else{
                req.setAttribute(Constants.MESSAGE,"新密码存在问题");
            }
            req.getRequestDispatcher("/main/updatePwd.jsp").forward(req,resp);
        }
    
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    注册 UserServlet

    <!--user-->
    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>com.qiu.servlet.user.UserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/main/user.do</url-pattern>
    </servlet-mapping>
    <servlet>
    

    编写常用工具类

    建立 util 包,然后建立常用变量工具类 Constants

    以后的常量放在工具类下

    public class Constants {
        public final static String USER_SESSION = "userSession";
        public final static String MESSAGE = "message";
    }
    

    编写注销功能

    思想:移除Session,然后重定向到登录页面

    在servlet包中的user包内建立LogoutServlet类

    public class LogoutServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //移除用户的Constants.USER_SESSION
            req.getSession().removeAttribute(Constants.USER_SESSION);
            resp.sendRedirect(req.getContextPath()+"/login/login.jsp");//返回登录页面
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    注册Servlet

    <!--logout-->
    <servlet>
        <servlet-name>logout</servlet-name>
        <servlet-class>com.qiu.servlet.user.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>logout</servlet-name>
        <url-pattern>/logout.do</url-pattern>
    </servlet-mapping>
    

    在jsp下面应用logout.do,以a标签为例

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    <a href="<c:url value="/logout.do"/>">退出</a>
    

    登录拦截优化

    思想:请求页面时,判断是否存在Session

    在 filter 包下建立登录过滤器 SysFilter

    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    public class SysFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {}
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
            //过滤器,从Session中获取用户
            User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
            if(user==null){ //已被移除或者注销了,或者未登录
                response.sendRedirect(request.getContextPath()+"/login/login.jsp");
            }else {
                chain.doFilter(req, resp);
            }
        }
    
        @Override
        public void destroy() {}
    }
    

    注册过滤器

    <!-- 用户登录过滤器-->
    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.qiu.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/main/*</url-pattern>
    </filter-mapping>
    

    UserServlet优化细节

    • 验证密码使用ajax及时动态优化
    • 实现Servlet复用
    • 使用前引入fastjson依赖
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    
    //实现Servlet复用
    public class UserServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String method = req.getParameter("method");
            if(method!=null && method.equals("savepwd")){
                this.updataPwd(req,resp);
            }else if(method!=null && method.equals("pwdmodify")){
                this.pwdModify(req,resp);
            }
        }
    
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    
        //修改密码
        public void updataPwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //从Session里面拿到username
            Object obj = req.getSession().getAttribute(Constants.USER_SESSION);
            String newpassword = req.getParameter("newpassword");
            boolean flag;
            if(obj!=null && !StringUtils.isNullOrEmpty(newpassword)){
                UserService userService = new UserServiceImpl();
                flag = userService.updatePwd(((User)obj).getUsername(),newpassword);
                if(flag){
                    req.setAttribute(Constants.MESSAGE,"密码修改成功,请退出重新登录");
                    req.getSession().removeAttribute(Constants.USER_SESSION);
                }else{
                    req.setAttribute(Constants.MESSAGE,"密码修改失败");
                }
            }else{
                req.setAttribute(Constants.MESSAGE,"新密码存在问题");
            }
            req.getRequestDispatcher("/main/updatePwd.jsp").forward(req,resp);
        }
    
        //验证旧密码,session中有用户的密码
        public void pwdModify(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            Object obj = req.getSession().getAttribute(Constants.USER_SESSION);
            String oldpassword = req.getParameter("oldpassword");
    
            //万能的Map:结果集
            Map<String,String> resultMap = new HashMap<String,String>();
            if(obj==null){//session失效过期了
                resultMap.put("result","sessionError");
            }else if(StringUtils.isNullOrEmpty(oldpassword)){   //输入的密码为空
                resultMap.put("result","error");
            }else{
                String userPassword = ((User)obj).getPassword();
                if(oldpassword.equals(userPassword)){
                    resultMap.put("result","true");
                }else{
                    resultMap.put("result","false");
                }
            }
            resp.setContentType("application/json");
            PrintWriter writer = resp.getWriter();
            //JSONArray 阿里巴巴的JSON工具类,转换格式
            writer.write(JSONArray.toJSONString(resultMap));
            writer.flush();
            writer.checkError();
        }
    }
    
    

    updatePwd.jsp 文件,根据环境做不同的修改

    <%@ page contentType="text/html;charset=UTF-8" %>
    <html>
    <head>
        <meta charset="utf-8">
        <title>修改密码</title>
        <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/login/css/style.css"/>
        <link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_1808293_ftumhpfd07g.css"/>
        <script src="${pageContext.request.contextPath}/login/js/jQuery.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
    <div class="form-wrapper">
        <div class="header">
            修改密码
        </div>
    
        <form action="${pageContext.request.contextPath}/main/user.do" method="post" class="update-form">
            <input type="hidden" name="method" value="savepwd">
            <div class="input-wrapper">
                <div class="border-wrapper">
                    <input id="oldpassword" type="password" name="password" placeholder="旧密码" class="border-item" value="" required/>
                </div>
                <div class="border-wrapper">
                    <input id="newpassword" type="password" name="newpassword" placeholder="新密码" class="border-item" value="" required/>
                </div>
                <div class="border-wrapper">
                    <input id="rnewpassword" type="password" name="rnewpassword" placeholder="确认密码" class="border-item" value="" required/>
                </div>
            </div>
            <div class="action">
                <div id="save" class="btn" onclick="send()">提交</div>
            </div>
        </form>
    
        <div id="message" style="color:red;font-size: 1.2em;margin-top: 20px">${message}</div>
    </div>
    <script>
        let oldpassword = null;
        let newpassword = null;
        let rnewpassword = null;
        let saveBtn = null;
        let message = null;
        let path = "${pageContext.request.contextPath}";
        $(function () {
            oldpassword = $("#oldpassword");
            newpassword = $("#newpassword");
            rnewpassword = $("#rnewpassword");
            saveBtn = $("#save");
            message = $("#message");
    
            oldpassword.on("focus",function (){
                message.html("请输入原来密码!");
             }).on("blur",function () {
                $.ajax({
                    type:"GET",
                    url:path+"/main/user.do",
                    data:{method:"pwdmodify",oldpassword:oldpassword.val()},
                    //上面等价于 path+"/main/user.do?method=pwdmodify&oldpassword=oldpassword.val()"
                    dataType:"json",
                    success:function (data) {
                        if(data.result === "true"){ //旧密码正确
                            message.html("旧密码验证成功!");
                        }else if(data.result ==="false"){
                            message.html("原密码输入不正确!");
                        }else if(data.result ==="sessionError"){
                            message.html("当前用户session过期,请重新登陆!");
                        }else if(data.result ==="error"){
                            message.html("请输入旧密码!");
                        }
                    },
                    error:function (data) {
                        //请求出错
                        message.html("请求出错!");
                    }
                });
            });
            //新密码
            newpassword.on("focus",function () {
                message.html("密码长度必须是大于6位小于20位!");
            }).on("blur",function () {
                if(newpassword.val()!=null && newpassword.val().length>=6
                    && newpassword.val().length<20){
                    message.html("新密码符合要求!");
                }else{
                    message.html("密码输入不符合规范,请重新输入");
                }
            });
    
            //确认密码
            rnewpassword.on("focus",function () {
                message.html("请输入与上面一致的密码");
            }).on("blur",function () {
                if(newpassword.val()!=null && newpassword.val().length>=6
                    && newpassword.val().length<20 && newpassword.val() === rnewpassword.val()){
                    message.html("确认密码符合要求!");
                }else{
                    message.html("两次密码输入不一致,请重新输入!");
                }
            });
    
        });
        function send(){
            if(message.html()==="密码修改成功,请退出重新登录" || (oldpassword.val().length!==0 && newpassword.val().length!==0 && rnewpassword.val().length!==0)){
                document.getElementsByClassName("update-form")[0].submit();
            }else{
                message.html("存在未填项,请重新检查!");
            }
        }
    </script>
    </body>
    </html>
    

    补充内容

    • 设置欢迎页和 Session 过期时间
    <!--  设置欢迎页-->
    <welcome-file-list>
        <welcome-file>/login/login.jsp</welcome-file>
    </welcome-file-list>
    <!--设置Session默认过期时间(分钟)-->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    
    • fastjson 依赖
    <!-- fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
    
    • 分包情况:pojo 包、 dao 包、 user包、 service 包、 servlet 包、 filter 包、 util
  • 相关阅读:
    中国历史朝代公元对照简表
    [Solved] DashBoard – Excel Service: The data sources may be unreachable, may not be responding, or may have denied you access.
    Delete/Remove Project from TFS 2010
    Sharepoint site showing system account instead of my username on the top right corner.
    你的成功在于你每天养成的习惯
    Internet Information Services is running in 32bit emulation mode. Correct the issue listed above and rerun setup.
    Prepare to back up and restore a farm (Office SharePoint Server 2007)
    Word中字号与磅值的对应关系
    How to: Change the Frequency for Refreshing the Data Warehouse for Team System
    UI Automation in WPF/Silverlight
  • 原文地址:https://www.cnblogs.com/qiu-m/p/13177974.html
Copyright © 2011-2022 走看看