“纸上得来终觉浅”,动手比看书印象更深,学到的更多。下面用Servlet实现简单的登陆功能,来巩固对Servlet的学习。
1、在WEB-INF下新建一个名为index.html作为登陆界面。
index.html代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form method='post' action='login.do'> <input type='text' name='username'><br/> <input type='password' name='password'><br/> <input type="submit" value="Login"> </form> </body> </html>
2、在src目录下,新建名为Login的Servlet
Login.java代码如下:
package com.demo; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ @WebServlet("/login.do") public class Login extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public Login() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if( loginCheck(username, password)){ //调用HttpServletRequest的getRequestDispatcher方法获得RequestDispatcher接口的对象实例 //调用时指定转发或包含的相对URL网址 //success.view 会依URL模式获取对应的Servlet //forward()方法:将请求转发给别的Servlet处理,相应的还有include()方法 request.getRequestDispatcher("success.view").forward(request, response); } else { //sendRedirect()方法要求浏览器重新请求另一个URL——重定向 //登录失败,则重定向到首页 response.sendRedirect("index.html"); } } private boolean loginCheck(String username, String password){ if( username!=null && password != null){ //这里还没有连接数据库,只是简单判断一下 if( username.equals("admin") && password.equals("123456")){ return true; } } return false; } }
注:在验证用户名和密码后,主要用到了RequestDispatcher调派请求。
include() 方法可以将其他Servlet流程包括到当前Servlet流程中。
forward() 方法将请求处理转发给别的Servlet。
在调派请求的过程中,如果有需要共享的对象,需要用到下面几个方法。
setAttribute() 方法设置共享对象。
getAttribute() 方法取得属性。
getAttributeName() 方法取得所有属性名称
removeAttribute() 方法指定名称移除属性。
3、在src下新建名为Success的Servlet,用来响应登陆成功的转发请求。
Success.java代码如下:
package com.demo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class Success */ @WebServlet("/success.view") public class Success extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public Success() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("</head>"); out.println("<body>"); out.println("<h2>"+ request.getParameter("username")+" 登陆成功!</h2>"); out.println("<script> document.write('update time:'+document.lastModified) </script>"); out.println("</body>"); out.println("</html>"); out.flush(); out.close(); } }
4、项目运行效果
登陆界面:
登陆成功:
注:请求转发是在容器中进行,所以可以取得WEB-INF中的资源,而浏览器不知道请求被转发了,地址栏不变。
用sendRedict()则要求浏览器重新请求另一个URL,地址栏会变更。
大部分情况下,使用HttpServletResponse的getWriter()来去的PrintWriter对象,使用println()等方法输出响应。
有时候,也可以直接对浏览器输出字节数据。需要使用getOutputStream()来取得ServletOutputStream实例。可以用来输出图片验证码。
下面就在登陆界面增加验证码功能。
5、新建名为SafeCode的Servlet用来生成验证码图片。
SafeCode.java 代码如下:
package com.demo; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; 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; public class SafeCode extends HttpServlet { /** * */ private static final long serialVersionUID = 1626673439350527994L; public SafeCode() { super(); } public void destroy() { super.destroy(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置输出类型和浏览器不保存缓存 response.setContentType("image/jpeg") ; response.setHeader("Cache-Control", "no-cache") ; //创建图片对象 int width = 60,height = 20 ; BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB) ; Graphics g = image.getGraphics() ; //生成随机数 Random random = new Random() ; String s = "" ; for(int i=0;i<4;i++){ s += random.nextInt(10) ; } //把随机数存到Session里面,便于等下比较 HttpSession session = request.getSession() ; session.setAttribute("code",s) ; //随机生成颜色 Color color = new Color(255,255,255) ; random.nextInt(256)的值范围是0~255 Color color = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256)) ; //把随机数写到图片上 String a = null ; Font font = new Font(a,Font.ITALIC,18) ; g.setColor(color) ; g.setFont(font); g.drawString(s,10,height-5) ; g.dispose() ; //关闭画笔 //把图片送到客户端 ServletOutputStream output = response.getOutputStream() ; ImageIO.write(image,"JPEG",output) ; output.flush(); //关闭输出流 } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request,response) ; } public void init() throws ServletException { } }
注:Servlet能输出各种格式的数据,用Context-Type属性进行设置。
6、在web.xml中添加如下配置
<servlet> <servlet-name>safeCode</servlet-name> <servlet-class>com.demo.SafeCode</servlet-class> </servlet> <servlet-mapping> <servlet-name>safeCode</servlet-name> <url-pattern>/safecode</url-pattern> </servlet-mapping>
7、在index.html中添加显示验证码的图片标签,和更新验证码的js脚本。注意:给图片设置src路径时,前面没有“/”,加了之后反而没法获取图片了。
<script> function reloadImage(){ document.getElementById('imgCode').src="safecode"; //alert("run"); } </script> ...... <img id="imgCode" src="safecode"/> <input type="button" value="看不清" id="btn" onclick="reloadImage()">
8、这样再次运行项目时,就会有验证码了,效果如下:
至于验证码的验证,前台后台都行,把输入的验证码跟HttpSession存的验证码做比较即可。这里就不再详细说明了。
综上:我们就实现了一个带验证码的简单登陆界面。对Servlet的请求、响应、转发与输出等知识点也有了一定的了解。
JavaWeb的核心构建在Servlet之上,对Servlet比较熟悉后,学习SSH等Web框架更能事半功倍。