在開始前冶伞,先把Tomcat的/lib/servlet-api.jar加入到項目依賴庫中割坠。
Servlet類繼承HttpServlet類麻汰,提供以下方法相應客戶端請求:
- doGet() 響應客戶端的get請求
- doPost() 響應客戶端的post請求
- doPut 和 doDelete落追,不常用,不去了解
另外偿洁,HttpServlet還有兩個方法:
- init() 創(chuàng)建Servlet實例時調用該方法
- destroy() 銷毀Servlet實例時調用該方法
練習######
配合JSP編寫一個小頁面撒汉,收集表單數(shù)據后打印在瀏覽器上。
form.jsp代碼如下
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<html>
<head>
<title>收集參數(shù)的表單頁</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等請求參數(shù)值
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參數(shù) -->
<servlet_name>firstServlet</servlet-name>
<!-- Servlet的實現(xiàn)類 -->
<servlet-class>包名.FirstServlet</servlet-class>
</servlet>
<!-- 配置Servlet的URL -->
<servlet-mapping>
<servlet-name>firstServlet</servlet-name>
<!-- 相當于@WebServlet中的urlPatterns參數(shù) -->
<url-pattern>/aaaa</url-pattern>
</servlet-mapping>
注意,方式b的生效優(yōu)先級高于方式a的宾肺。
load-on-start Servlet######
通常在收到客戶端請求后才會創(chuàng)建Servlet實例溯饵,但通過下面兩種配置方式,可以在應用啟動時立即創(chuàng)建Servlet實例
@WebServlet(loadOnStartup=1)
- web.xml中在<servlet>標簽內添加
<load-on-startup>1</load-on-startup>
該參數(shù)接收一個整數(shù)值锨用,值越小加載順序越靠前
比如需要每秒在控制臺輸出當前系統(tǒng)時間丰刊,可以這樣寫
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的配置參數(shù)######
用以下兩種方式為Servlet配置額外的參數(shù)
- @WebServlet中的Initparams參數(shù)
@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>```
當需要使用這些參數(shù)時,通過ServletConfig對象的getInitParameter(String name)方法獲取初始化參數(shù)
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{
//獲取初始化參數(shù)
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();
//執(zhí)行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的初始化參數(shù)</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)類似于調度員藻三,將用戶請求分發(fā)給Model來處理洪橘,并調用JSP(View)展示結果跪者。
Model通常由JavaBean充當,所有業(yè)務邏輯熄求、數(shù)據訪問等工作都在Model中實現(xiàn)渣玲。
下面實現(xiàn)一個簡單的登陸驗證功能:
在登陸頁面輸入用戶名與密碼,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對比數(shù)據庫忘衍,根據結果不同轉發(fā)到不同的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本身并不輸出響應到客戶端卿城,因此必須將請求轉發(fā)
RequestDispatcher rd;
//獲取請求參數(shù)
String username = request.getParameter("uesrname");
String pass = request.getParameter("pass");
try{
//獲取初始化參數(shù)
ServletConfig config = getServletConfig();
String driver = config.getInitParameter("driver");
String url = config.getInitParameter("url");
String user = config.getInitParameter("user");
String password = config.getInitParameter("password");
//調用JavaBean,查詢數(shù)據庫
DbDao dd = new DbDao(driver, url, user, password);
String sql = "select pass from user_table where name = ";
ResultSet rs = dd.query(sql + username);
//將結果轉發(fā)到不同的jsp
if (rs.next()){
if (rs.getString("pass").equals(pass)){
//獲取session對象
HttpSession session = request.getSession(true);
//設置sessions屬性枚钓,跟蹤用戶會話狀態(tài)
session.setAttribute("name",username);
//獲取轉發(fā)對象
rd = request.getRequestDispatcher("/welcom.jsp");
//轉發(fā)請求
rd.forward(request,response);
}
else{
errMessage += "輸入的用戶名或密碼不正確";
}
}
else{
errMessage += "用戶名不存在";
}
}
catch (Exception e){
e.printStackTrace();
}
//如果出錯,轉發(fā)到重新登入
if (errMessage != null && !errMessage.equals("")){
rd = request.getRequestDispatcher("/login.jsp");
request.setAttribute("err", errMessage);
rd.forward(request,response);
}
}
}
DbDao.java用于連接和操作數(shù)據庫
import java.sql.*;
/**
-
封裝了數(shù)據庫的增刪改查功能
*/
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;
}//獲取數(shù)據庫連接
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();
}//關閉數(shù)據庫連接
public void closeConn() throws SQLException {
if (conn != null && !conn.isClosed()){
conn.close();
}
}
}
如果輸入的用戶名和密碼有錯誤瑟押,則轉發(fā)到login.jsp搀捷,并展示錯誤信息。
否則,登陸成功嫩舟,轉到welcom.jsp氢烘,如下
<html>
<head>
<title>登入成功</title>
</head>
<body>
<% out.print(request.getParameter("username") + ",歡迎回來家厌!"); %>
</body>
</html>