4.2 简单Java Web项目举例
今天以登录功能为例,完成在不用spring等框架的情况下如何搭建一个简单的Java Web项目。
- HttpServlet 了解
通过浏览器对系统的访问,我们通常叫http请求,Java Web系统对http请求是通过HttpServlet接收处理的,HttpServlet容器响应Web客户请求流程如下:
- 1)Web客户向Servlet容器(或叫web容器,例如Tomcat)发出Http请求;
- 2)Servlet容器解析Web客户的Http请求;
- 3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;
- 4)Servlet容器创建一个HttpResponse对象;
- 5)Servlet容器调用HttpServlet的service方法,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;
- 6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
- 7)HttpServlet调用HttpResponse的有关方法,生成响应数据;
- 8)Servlet容器把HttpServlet的响应结果传给Web客户。
我用下划线画出来了在流程中的几个元素:HTTP请求+信息,servlet容器,HttpServlet对象,HttpRequest对象,HttpResponse对象,流程中元素之间的交互概括如下图:
接下来的开发,就是针对每个元素进行的处理。
- Java Web项目创建
这个项目我们就只做个简单的登录功能。
我们在Java Web开发准备这个内容已经把环境配置好了,包括tomcat(Servlet容器),接下来就需要我们完成三点:
- ①提供页面,输入登录信息,提交后能发起请求(Web客户);
- ②获取请求信息,查询数据库,取得用户信息进行对比 (HttpServlet对象,HttpRequest对象,HttpResponse对象)
- ③把对比处理结果反馈到页面上(HttpResponse对象)
- 1)新建数据库和表格
新建数据库ecom;
新建user表格并初始化,sql如下:
-- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(255) NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `email` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('2', 'sophia', '123456', '[email protected]');
- 2)新建Web Project
- File->new->web project,填入项目名SimpleJavaWeb,如下:
- 3)新建用户类User和数据库操作类
根据输入的email信息,查询数据库获得用户信息,返回一个User类的对象。
User.java:
package com.test; public class User { String email; String username; String password; public User(String email,String username,String password){ this.email = email; this.username = username; this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
数据库操作类JDBCUtils.java:
package com.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * JDBC连接数据库 * 详细可参考http://www.cnblogs.com/Qian123/p/5339164.html * @author jxh */ public class JDBCUtils { private static final String URL="jdbc:mysql://localhost:3306/ecom"; private static final String NAME="jxh"; private static final String PASSWORD="123456"; private static Connection conn=null; //静态代码块(将加载驱动、连接数据库放入静态块中) static{ try { //1.加载驱动程序 Class.forName("com.mysql.jdbc.Driver"); //2.获得数据库的连接 conn = DriverManager.getConnection(URL, NAME, PASSWORD); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } public JDBCUtils(){} //对外提供一个方法来获取数据库连接 public static Connection getConnection(){ return conn; } public static User getUserInfo(String email) throws Exception{ //3.通过数据库的连接操作数据库,实现增删改查 String sql = "select email,username,password from user where email = ?"; PreparedStatement psmt = conn.prepareStatement(sql); psmt.setString(1, email); ResultSet rs = psmt.executeQuery(); //如果对象中有数据,就会循环打印出来 while(rs.next()){ System.out.println(rs.getString("email")+","+rs.getString("username")+","+rs.getString("password")); return new User(rs.getString("email"),rs.getString("username"),rs.getString("password")); } return null; } }
这个类能正确运行,还需要下载mysql-connector-java-5.1.39.jar,放到WebRoot\WEB-INF\lib\下
- 4)创建登录页面及其他
login.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; Object obj = request.getAttribute("msg"); String msg = ""; if(obj!=null){ msg = obj.toString(); } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <!-- 设置页面内所有连接的相对路径,必须放在head标签里 --> <base href="<%=basePath%>"> <title>My JSP 'index.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 style="text-align: center;"> <div> <form action="login.do"> <table> <th> <tr>邮箱</tr> <tr><input name="email" type="text"/></tr> </th> <th> <tr>密码</tr> <tr><input name="password" type="text"/></tr> </th> <th> <tr><input type="submit" value="登录"/></tr> <tr><%=msg%></tr> </th> </table> </form> </div> </body> </html>
其中 request.getAttribute("msg");用来在页面打开时,获取request中的操作错误的提示信息,第一次打开页面这个肯定是没有值的。
登录成功显示页面success.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% 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> <!-- 设置页面内所有连接的相对路径,必须放在head标签里 --> <base href="<%=basePath%>"> <title>My JSP 'index.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 style="text-align: center;"> <div>欢迎,尊敬的<%=request.getAttribute("usr")%>,您登录成功! </div> </body> </html>
登录错误提示页面err.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% 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> <!-- 设置页面内所有连接的相对路径,必须放在head标签里 --> <base href="<%=basePath%>"> <title>My JSP 'index.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> <div> 登录出错,请联系管理人员! </div> </body> </html>
- 5)自定义HttpServlet
创建自定义的HttpServlet,这里命名为SimpleJavaWebServlet,用来接收请求,并按照我们自己的需求作出处理和请求反馈。
(HTTP的请求方式包括DELETE,GET,OPTIONS,POST,PUT和TRACE,在HttpServlet类中分别提供了相应的服务方法,它们是,doDelete(),doGet(),doOptions(),doPost(), doPut()和doTrace(),常用的就用doGet()和doPost()两个)
SimpleJavaWebServlet.java 代码如下:
package com.test; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class SimpleJavaWebServlet extends HttpServlet { // 注意 // request.getRequestDispatcher("/(正斜杠)加文件名(从webroot下开始算)").forward(request, // response); // response.sendRedirect("/(正斜杠)+项目名+文件名(从webroot下开始算。所有servlet文件都算作在webroot的跟目录下。不需要加包名)"); protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String email = req.getParameter("email"); String password = req.getParameter("password"); if (email == null || password == null) { req.setAttribute("msg", "邮箱和密码都不能为空"); req.getRequestDispatcher("/login.jsp").forward(req, resp); return; } try { User usr = JDBCUtils.getUserInfo(email); if (usr == null) { req.setAttribute("msg", "邮箱不存在"); req.getRequestDispatcher("/login.jsp").forward(req, resp); return; } if (!password.equals(usr.getPassword())) { req.setAttribute("msg", "密码不正确"); req.getRequestDispatcher("/login.jsp").forward(req, resp); return; } req.setAttribute("usr", usr.getUsername()); req.getRequestDispatcher("/success.jsp").forward(req, resp); return; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } req.getRequestDispatcher("/err.jsp").forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
- 6)配置web.xml
将我们定义的simpleJavaWebServlet配置到web中,就是告诉项目用这个servlet启动,并作为容器处理相关请求。
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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_2_5.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 配置自定义servlet --> <servlet> <servlet-name>simpleJavaWebServlet</servlet-name> <servlet-class>com.test.SimpleJavaWebServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>simpleJavaWebServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
- 7)测试
到目前项目结构:
右击项目,run as->run on server,成功启动后,在浏览器中输入http://localhost:8080/SimpleJavaWeb/login.jsp回车:
测试多种情况:
- ①邮箱和密码都没有输入,点击登录
- ②邮箱和密码其中之一没有输入,点击登录
- ③邮箱输入[email protected],密码跟数据库中的不一样
- ④邮箱输入[email protected],密码123456
- 登录成功的页面如下:
简单的Java Web项目完成!