1. 本章任务
目前已经实现了数据库表结构搭建、项目构建、数据库实体类编写、数据库操作类编写。
接下来可以实现登录功能了,还是需要先登录,才能对各角色的功能页面进行相应的展示和管理。
PS:本章内容可以说是教程中最重要的1章,因为封装了前后端交互的方式,我们来一步一步详细讲解下,如果理解了本章,后续应该没多大难度了。
2. 开发流程
首先需要在登录页面开发登录表单,点击表单后跳转Servlet处理登录请求。
Servlet中调用UserDao判断是否登录成功。
如果登录成功,则将登录用户信息加入Session备用,并且跳转主页面。
如果登录失败,返回错误提示信息。
3. 开发登录页面表单
3.1 新建登录页
首先新建index.html作为登录页,注意我们通过ajax请求后端数据的话,实际上是不需要再使用JSP这种模板技术了。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>index.html.html</title> </head> <body> </body> </html> 注意编码采用UTF-8以支持中文。 3.2 引入EasyUI支持 由于我们使用EasyUI框架,而EasyUI又依赖于jQuery,所以我们引入相关的样式css文件及js文件。 <link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css"> <script type="text/javascript" src="easyui/jquery.min.js"></script> <script type="text/javascript" src="easyui/jquery.easyui.min.js"></script> 有了css和js引入,我们就可以在网页中使用EasyUI封装好的样式和js方法了。 3.3 开发登录表单 需要通过登录名和密码登录。 <body> <div class="container"> <div class="easyui-panel" title="登录" style="background: #fafafa; width: 100%; height: 100%;"> <div class="input-box"> <label for="name">用户名:</label> <input class="easyui-textbox" type="text" id="loginName" data-options="required:true"> </div> <div class="input-box"> <label for="email">密码:</label> <input class="easyui-textbox" type="text" id="password" data-options="required:true"> </div> <div class="input-box"> <a id="btn" onclick="loginAction()" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-ok'">登录</a> </div> </div> </div> </body> 注意,我们通过easyui-panel、easyui-textbox等EasyUI提供的样式类,为我们的页面标签设定了EasyUI风格。 3.4 微调样式 虽然已经使用EasyUI但是部分细节还是需要使用css调整下,注意有个原则是尽量使用EasyUI提供的样式。 <style> .container { width: 500px; height: 500px; margin: 0 auto; padding-top: 200px; } .input-box { margin: 32px 0px 0px 128px; } .input-box label { display: inline-block; width: 64px; } </style> 3.5 编写登录方法 最后我们就需要通过js编写登录方法了,由于在登录按钮上已经绑定了onclick="loginAction()",所以我们编写loginAction方法即可。 <script> // 登录 function loginAction() { console.log("loginAction"); var param = { loginName : $("#loginName").val(), password : $("#password").val() } $.ajax({ url : "CoreServlet?method=login", type : "post", dataType : "json", data : param, success : function(res) { console.log(res);//暂时打印后端返回结果 }, }); } </script> 注意:<script>标签的位置是</body>之后</html>之前。 然后点击后,会将用户loginName、密码password信息提交到CoreServlet?method=login处理。 最后还需要注意的是,为了方便处理返回值,我们要求返回值的类型为dataType : "json",,也就CoreServlet需要返回json类型返回值。 4. 开发CoreServlet控制器处理登录请求 4.1 统一返回值格式 前面说了,网页和控制器交互的方式就是通过ajax方法,为了便于前端统一处理,我们规定后端统一返回一个对象。 /** * 统一返回结果类 */ public class Result<T> { /** * 0成功 9999失败 */ private int code; /** * 提示信息 */ private String msg; /** * 返回数据 */ private T data; // 省略 get set } 注意,如果后台处理成功,则code=0,此时如果有返回数据放到data里即可,由于data是泛型,所以可以接受任何类型的数据。 如果后台处理失败或者有异常,则code=9999,且msg存放错误提示信息(例如异常信息)。 这样的话,前端只需要根据返回内容的code值就可以进行相应处理了。 而不是每次调用一个后端接口,都要分类处理,统一处理可以大大减轻前后端交互的负担! 4.2 在CoreServlet中分类处理请求 代码如下,看完再仔细解释。 @WebServlet("/CoreServlet") public class CoreServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置输入输出格式、编码 response.setContentType("text/html"); request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); // 获取writer方法,用于将数据返回给ajax // 获取用户在网页输入的用户名和密码 Result result = null; try { result = handleRequest(request); } catch (Exception ex) { result = new Result(); result.setCode(9999); result.setMsg(ex.getMessage()); } finally { out.write(JSON.toJSONString(result)); out.flush(); out.close(); } } /** * 具体处理请求 */ public Result handleRequest(HttpServletRequest request) throws Exception { Result result = new Result(); String method = request.getParameter("method"); // 登录处理 if (method.equals("login")) { result.setCode(0); result.setMsg("操作成功"); } // 其他处理放于此处 return result; } } 首先handleRequest方法具体执行请求处理,如果处理过程中有异常,则返回code=9999且msg带异常信息的Result对象。 如果处理正常的话,就返回code=0且msg为操作成功的Result对象。 最后需要注意,我们ajax方法要求返回值是json,所以将result通过JSON.toJSONString(result)序列化为json字符串返回给网页。 JSON.toJSONString方法需要添加jar包:fastjson-1.2.74.jar,可以自行下载,或者通过我给出的GitHub链接下载。 4.3 处理登录请求 本篇真正要实现的功能来了,处理登录请求。这个就比较简单了,代码如下: /** * 具体处理请求 */ public Result handleRequest(HttpServletRequest request) throws Exception { Result result = new Result(); String method = request.getParameter("method"); // 登录处理 if (method.equals("login")) { String loginName = request.getParameter("loginName"); String password = request.getParameter("password"); UserDao userDao = new UserDao(); List<User> users = userDao.getUsersByLoginNameAndPassword(loginName, password); if (users != null && users.size() == 1) {// 登录成功 result.setCode(0); result.setMsg("操作成功"); result.setData(users.get(0)); request.getSession().setAttribute("loginUser", users.get(0)); } else {// 登录失败 result.setCode(9999); result.setMsg("操作失败"); } } // 其他处理放于此处 return result; } 4.4 前端处理返回结果 后端将result返回给前端后,前端就可以直接处理了。 <script> // 登录 function loginAction() { console.log("loginAction"); var param = { loginName : $("#loginName").val(), password : $("#password").val() } $.ajax({ url : "CoreServlet?method=login", type : "post", dataType : "json", data : param, success : function(res) { console.log(res); if (res.code == 0) {//登录成功 window.location.href = "main.html"; } else {//登录失败直接提示错误信息 alert(res.msg); } }, }); } </script> 5. 测试 启动项目后打开http://localhost:8080/scholar-system/index.html。 然后在user表构造一条loginName password均为1的数据。 然后输入1/1登录即可验证。 推进使用debug模式,然后再CoreServlet中下断点,来跟进程序的运行过程,加深理解。 效果如下:
//