JSP 仅能作为表现层(View)技术,作用有两点:
1. 负责收集用户请求参数。
2. 将应用的处理结果、状态数据呈现给用户。
Servlet 则仅充当控制器(Controller)角色,用户类似于调度员:(所以用户的请求发送给 Servlet , Servlet 调用 Model 来处理用户请求,并调用 JSP 来呈现处理结果;)
Model 通常由 JavaBean 来充当,所以业务逻辑、数据访问逻辑都在 Model 中实现。
login.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 用户登录 </title>
</head>
<body>
<!-- 输出出错提示 -->
<span style="color:red;font-weight:bold">
<% // 错误提示
if (request.getAttribute("err") != null)
{
out.println(request.getAttribute("err") + "<br/>");
}
%>
</span>
请输入用户名和密码:
<!-- 登录表单,该表单提交到一个Servlet -->
<form id="login" method="post" action="login">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="password" name="pass"/><br/>
<input type="submit" value="登录"/><br/>
</form>
</body>
</html>
简单的表单页面,收集用户名和密码,并将请求提交到指定的 Servlet ,如下 Servlet 充当控制器角色
LoginServlet.java
package lee;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.PrintWriter;
import java.io.IOException;
import java.sql.*;
@WebServlet(name="login"
, urlPatterns={"/login"})
public class LoginServlet extends HttpServlet
{
//响应客户端请求的方法
public void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,java.io.IOException
{
String errMsg = "";
//Servlet本身并不输出响应到客户端,因此必须将请求转发
RequestDispatcher rd;
//获取请求参数
String username = request.getParameter("username");
String pass = request.getParameter("pass");
try
{
//Servlet本身,并不执行任何的业务逻辑处理,它调用JavaBean处理用户请求
DbDao dd = new DbDao("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/liuyan","root","");
//查询结果集
ResultSet rs = dd.query("select pass from user_table "
+ "where name = ?", username);
if (rs.next())
{
//用户名和密码匹配
if (rs.getString("pass").equals(pass))
{
//获取session对象
HttpSession session = request.getSession(true);
//设置session属性,跟踪用户会话状态
session.setAttribute("name" , username);
//获取转发对象
rd = request.getRequestDispatcher("/welcome.jsp");
//转发请求
rd.forward(request,response);
}
else
{
//用户名和密码不匹配时
errMsg += "您的用户名密码不符合,请重新输入";
}
}
else
{
//用户名不存在时
errMsg += "您的用户名不存在,请先注册";
}
}
catch (Exception e)
{
e.printStackTrace();
}
//如果出错,转发到重新登录
if (errMsg != null && !errMsg.equals(""))
{
rd = request.getRequestDispatcher("/login.jsp");
request.setAttribute("err" , errMsg);
rd.forward(request,response);
}
}
}
控制器负责接收客户端的请求,然后调用 JavaBean 来处理用户请求。 上面 Servlet 使用 @WebServlet Annoation 为该Servlet 配置了 URL 为 /login ,因此向 /login 发送的请求将交给该 Servlet 处理。
DbDao.java
package lee;
import java.sql.*;
public class DbDao
{
private Connection conn;
private String driver;
private String url;
private String username;
private String pass;
public DbDao()
{
}
public DbDao(String driver , String url
, String username , String pass)
{
this.driver = driver;
this.url = url;
this.username = username;
this.pass = pass;
}
//下面是各个成员属性的setter和getter方法
public void setDriver(String driver) {
this.driver = driver;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getDriver() {
return (this.driver);
}
public String getUrl() {
return (this.url);
}
public String getUsername() {
return (this.username);
}
public String getPass() {
return (this.pass);
}
//获取数据库连接
public Connection getConnection() throws Exception
{
if (conn == null)
{
Class.forName(this.driver);
conn = DriverManager.getConnection(url,username,
this. pass);
}
return conn;
}
//插入记录
public boolean insert(String sql , Object... args)
throws Exception
{
PreparedStatement pstmt = getConnection().prepareStatement(sql);
for (int i = 0; i < args.length ; i++ )
{
pstmt.setObject( i + 1 , args[i]);
}
if (pstmt.executeUpdate() != 1)
{
return false;
}
pstmt.close();
return true;
}
//执行查询
public ResultSet query(String sql , Object... args)
throws Exception
{
PreparedStatement pstmt = getConnection().prepareStatement(sql);
for (int i = 0; i < args.length ; i++ )
{
pstmt.setObject( i + 1 , args[i]);
}
return pstmt.executeQuery();
}
//执行修改
public void modify(String sql , Object... args)
throws Exception
{
PreparedStatement pstmt = getConnection().prepareStatement(sql);
for (int i = 0; i < args.length ; i++ )
{
pstmt.setObject( i + 1 , args[i]);
}
pstmt.executeUpdate();
pstmt.close();
}
//关闭数据库连接的方法
public void closeConn()
throws Exception
{
if (conn != null && !conn.isClosed())
{
conn.close();
}
}
}
DbDao 负责完成查询、插入、修改等操作。
注:(以上数据库为 liuyan , 表为 user_table , 字段为 name,pass)
操作演示:
1.输入错误的用户名和密码
2.输入存在的用户 ,但输入错误的密码
3.输入正确的用户和密码