在开始前,先把Tomcat的/lib/servlet-api.jar加入到项目依赖库中。
Servlet类继承HttpServlet类,提供以下方法相应客户端请求:
- doGet() 响应客户端的get请求
- doPost() 响应客户端的post请求
- doPut 和 doDelete,不常用,不去了解
另外,HttpServlet还有两个方法:
- init() 创建Servlet实例时调用该方法
- destroy() 销毁Servlet实例时调用该方法
练习######
配合JSP编写一个小页面,收集表单数据后打印在浏览器上。
form.jsp代码如下
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<html>
<head>
<title>收集参数的表单页</title>
</head>
<body>
<form id="form1" method="post" action="firstServlet">
用户名:<br />
男<input type="radio" name="gander" value="男">
女<input type="radio" name="gander" value="女">
喜欢的颜色:<br />
红<input type="checkbox" name="color" value="红">
绿<input type="checkbox" name="color" value="绿">
红配绿<input type="checkbox" name="color" value="红配绿">
国籍:<br />
<select name="country">
<option value="China">China</option>
<option value="Russia">Russia</option>
<option value="Vietname">Vietname</option>
</select><hr />
<input type="submit" value="SUBMIT">
<input type="reset" value="RESET">
</form>
</body>
</html>
FIrstServlet.java代码如下
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintStream;
/**
* Created by FanXiao on 2017/5/11.
*/
@WebServlet(name="firstServlet",urlPatterns={"/firstServlet"})
public class FirstServlet extends HttpServlet{
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
//设置解码方式
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charSet=GBK");
//获取name、gender、color和country等请求参数值
String name = request.getParameter("name");
String gender = request.getParameter("gender");
String[] color = request.getParameterValues("color");
String country = request.getParameter("country");
//获取out
PrintStream out = new PrintStream((response.getOutputStream()));
//输出html页面
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet测试");
out.println("</head>");
out.println("name:" + name + "<hr/>");
out.println("gender:" + gender + "<hr/>");
out.println("colors");
for (String c : color){
out.println(c + " ");
}
out.println("<hr/>");
out.println("country:" + country + "<hr/>");
out.println("</body>");
out.println("</html>");
}
}
Servlet的两种配置方式######
a) 在注释中配置
@WebServlet(name="firstServlet",urlPatterns={"/firstServlet"})
b) 在web.xml中配置
<!-- 配置Servlet的名字 -->
<servlet>
<!-- 相当于@WebServlet中的name参数 -->
<servlet_name>firstServlet</servlet-name>
<!-- Servlet的实现类 -->
<servlet-class>包名.FirstServlet</servlet-class>
</servlet>
<!-- 配置Servlet的URL -->
<servlet-mapping>
<servlet-name>firstServlet</servlet-name>
<!-- 相当于@WebServlet中的urlPatterns参数 -->
<url-pattern>/aaaa</url-pattern>
</servlet-mapping>
注意,方式b的生效优先级高于方式a的。
load-on-start Servlet######
通常在收到客户端请求后才会创建Servlet实例,但通过下面两种配置方式,可以在应用启动时立即创建Servlet实例
@WebServlet(loadOnStartup=1)
- web.xml中在<servlet>标签内添加
<load-on-startup>1</load-on-startup>
该参数接收一个整数值,值越小加载顺序越靠前
比如需要每秒在控制台输出当前系统时间,可以这样写
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
@WebServlet(loadOnStartup = 1)
public class Clock extends HttpServlet{
public void init(ServletConfig config) throws ServletException {
super.init(config);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(new Date());
}
},0,1000);
}
}
Servlet的配置参数######
用以下两种方式为Servlet配置额外的参数
- @WebServlet中的Initparams参数
@WebServlet (name="testServlet", urlPatterns={"testServlet"},
initParams={
@WebInitParam(name="driver", value="com.mysql.jdbc,Driver"),
@WebInitParam(name="url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name="user", value="root"),
@WebInitParam(name="password", value="123456")}) ```
* web.xml文件的<servlet>标签内添加<init-param>子标签
```<servlet>
<init-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</init-param>
</servlet>```
当需要使用这些参数时,通过ServletConfig对象的getInitParameter(String name)方法获取初始化参数
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
@WebServlet(name="testServlet", urlPatterns={"testServlet"},
initParams={
@WebInitParam(name="driver", value="com.mysql.jdbc.Driver"),
@WebInitParam(name="url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name="user", value="root"),
@WebInitParam(name="password", value="123456")})
public class TestServlet extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response){
try{
//获取初始化参数
ServletConfig config = getServletConfig();
String driver = config.getInitParameter("driver");
String url = config.getInitParameter("url");
String user = config.getInitParameter("user");
String password = config.getInitParameter("password");
//链接mysql
Class.forName(driver);
Connection conn = DriverManager.getConnection(url,user,password);
Statement stmt = conn.createStatement();
//执行sql语句
ResultSet rs = stmt.executeQuery("select * from table_1");
//将查询结果输出到网页
response.setContentType("text/html;charSet=GBK");
PrintStream out = new PrintStream((response.getOutputStream()));
out.println("<html>");
out.println("<head>");
out.println("<title>访问Servlet的初始化参数</titlet>");
out.println("</head>");
out.println("<body>");
out.println("<table>");
while(rs.next()){
out.println("<tr>");
out.println("<td>" + rs.getString(1) + "</td>");
out.println("<td>" + rs.getString(2) + "</td>");
out.println("</tr>");
}
out.println("</table>");
out.println("</body>");
out.println("</html>");
}
catch (Exception e){
e.printStackTrace();
}
}
}
######在MVC中,Servlet是Controller######
Servlet(Controller)类似于调度员,将用户请求分发给Model来处理,并调用JSP(View)展示结果。
Model通常由JavaBean充当,所有业务逻辑、数据访问等工作都在Model中实现。
下面实现一个简单的登陆验证功能:
在登陆页面输入用户名与密码,login.jsp如下
<html>
<head>
<title>用户登入</title>
</head>
<body>
<span>
<% if(request.getAttribute("err") != null){
out.println(request.getAttribut("err") + "</br>);
} %>
</span>
输入用户名与密码
<form id="login" method="post" action="login">
用户名:<input type="text" name="username"/>
密码:<input type="password" name="pass"/>
<input type="submit" value="登入"/>
</form>
</body>
</html>
从login.jsp采集到用户名和密码后,调用JavaBean对比数据库,根据结果不同转发到不同的jsp。LoginServlet.java如下
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.ResultSet;
@WebServlet(name="login", urlPatterns = {"/login"},
initParams={
@WebInitParam(name="driver", value="com.mysql.jdbc,Driver"),
@WebInitParam(name="url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name="user", value="root"),
@WebInitParam(name="password", value="123456")})
public class LoginServlet extends HttpServlet{
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String errMessage = "";
//Servlet本身并不输出响应到客户端,因此必须将请求转发
RequestDispatcher rd;
//获取请求参数
String username = request.getParameter("uesrname");
String pass = request.getParameter("pass");
try{
//获取初始化参数
ServletConfig config = getServletConfig();
String driver = config.getInitParameter("driver");
String url = config.getInitParameter("url");
String user = config.getInitParameter("user");
String password = config.getInitParameter("password");
//调用JavaBean,查询数据库
DbDao dd = new DbDao(driver, url, user, password);
String sql = "select pass from user_table where name = ";
ResultSet rs = dd.query(sql + username);
//将结果转发到不同的jsp
if (rs.next()){
if (rs.getString("pass").equals(pass)){
//获取session对象
HttpSession session = request.getSession(true);
//设置sessions属性,跟踪用户会话状态
session.setAttribute("name",username);
//获取转发对象
rd = request.getRequestDispatcher("/welcom.jsp");
//转发请求
rd.forward(request,response);
}
else{
errMessage += "输入的用户名或密码不正确";
}
}
else{
errMessage += "用户名不存在";
}
}
catch (Exception e){
e.printStackTrace();
}
//如果出错,转发到重新登入
if (errMessage != null && !errMessage.equals("")){
rd = request.getRequestDispatcher("/login.jsp");
request.setAttribute("err", errMessage);
rd.forward(request,response);
}
}
}
DbDao.java用于连接和操作数据库
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;
}public String getDriver() {
return driver;
}public void setDriver(String driver) {
this.driver = driver;
}public String getUrl() {
return url;
}public void setUrl(String url) {
this.url = url;
}public String getUsername() {
return username;
}public void setUsername(String username) {
this.username = username;
}public String getPass() {
return pass;
}public void setPass(String pass) {
this.pass = pass;
}//获取数据库连接
public Connection getConnection() throws ClassNotFoundException, SQLException {
if (conn == null){
Class.forName(this.driver);
conn = DriverManager.getConnection(url, username, pass);
}
return conn;
}//插入
public boolean insert(String sql, Object... args) throws SQLException, ClassNotFoundException {
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;
}
return true;
}//查询
public ResultSet query(String sql, Object... args) throws SQLException, ClassNotFoundException {
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 SQLException, ClassNotFoundException {
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 SQLException {
if (conn != null && !conn.isClosed()){
conn.close();
}
}
}
如果输入的用户名和密码有错误,则转发到login.jsp,并展示错误信息。
否则,登陆成功,转到welcom.jsp,如下
<html>
<head>
<title>登入成功</title>
</head>
<body>
<% out.print(request.getParameter("username") + ",欢迎回来!"); %>
</body>
</html>