servlethtml
servlet:
定義:動態的web開發技術,本質是一個類,是運行在服務器端的一個java小程序
做用:處理業務邏輯,生成動態web內容
編寫一個servlet步驟: 1.編寫一個類 a.繼承HttpServlet b.重寫doGet或者doPost方法 2.編寫配置文件(web-inf/web.xml) a.註冊servlet b.綁定路徑 3.訪問 http://主機:端口號/項目名/路徑
接受參數: 格式:key=value String value=request.getParameter("key") 例如: http://localhost/day09/hello?username=tom
request.getParameter("username")就能夠獲取tom值
回寫內容: response.getWriter().print("success"); 處理響應數據中文亂碼: response.setContentType("text/html;charset=utf-8"); //建議你們放在方法中的第一行
小案例:java
ServletTest01.java源碼:mysql
package com.servlet.hjh.day0529; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletTest01 extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String value =req.getParameter("username"); System.out.println(value); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
web.xml配置文件:web
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>ServletTest01</servlet-name>
<servlet-class>com.servlet.hjh.day0529.ServletTest01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest01</servlet-name>
<url-pattern>/test01</url-pattern>
</servlet-mapping>
</web-app>
index.htmlsql
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="http://localhost:8080/Servlet/test01?username=hjh">request請求參數示例</a>
</body>
</html>
啓動tomcat服務器,瀏覽器中輸入,回車,顯示「request請求參數示例」。當點擊這個超連接時,頁面刷新,發送一個帶參數的請求「http://localhost:8080/Servlet/test01?username=hjh」。servlet類的「req.getParameter("username");」方法獲取了url中的username的值hjh,進行輸出。數據庫
往瀏覽器回寫數據,會出現中文亂碼:;使用resp.setContentType("text/html;charset=utf-8")設置瀏覽器輸出的編碼格式apache
package com.servlet.hjh.day0529; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletTest01 extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲取url參數
String value =req.getParameter("username"); System.out.println(value); //往瀏覽器回寫數據 //resp.getWriter().print("用戶名username="+value);//???username=hjh 出現亂碼 //設置瀏覽器輸出的編碼格式
resp.setContentType("text/html;charset=utf-8"); resp.getWriter().print("用戶名username="+value);//用戶名username=hjh
} @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
LoginServlet案例:小程序
數據庫:瀏覽器
create database hejh; use hejh; create table user( id int primary key auto_increment, username varchar(20), password varchar(20), email varchar(20), name varchar(20), sex varchar(10), birthday date, hobby varchar(50) ); insert into user values (null,'hjh','123','hjh@126.com','hjh','1','1988-01-01',null);
案例的項目結構:tomcat
導包要注意,不能少!!!!
UserDao.java源碼
package com.hjh.dao; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import com.hjh.domain.User; import com.hjh.util.DataSourseUtils; public class UserDao { public User findUserByUsernameAndPassword(String username, String password) throws SQLException { //建立QueryRunner對象,操做sql語句
QueryRunner qr = new QueryRunner(new DataSourseUtils().getDataSourse()); //編寫sql語句
String sql = "select * from user where username=? and password=?"; //執行sql BeanHandler, 將查詢結果的第一條記錄封裝成指定的bean對象,返回
User user = qr.query(sql, new BeanHandler<User>(User.class),username,password); //返回user對象
return user; } }
User.java源碼:
package com.hjh.domain; public class User { private int id; private String username; private String password; public User() {} public User(int id,String username,String password) { this.id = id; this.username = username; this.password = password; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; } }
UserService.java源碼:
package com.hjh.service; import java.sql.SQLException; import com.hjh.dao.UserDao; import com.hjh.domain.User; public class UserService { public User login(String username, String password) { User user = null; try { user = new UserDao().findUserByUsernameAndPassword(username,password); } catch (SQLException e) { e.printStackTrace(); } return user; } }
LoginServlet.java源碼
package com.hjh.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hjh.domain.User; import com.hjh.service.UserService; public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.設置編碼
response.setContentType("text/html;charset=utf-8"); //2.接收用戶名和密碼
String username = request.getParameter("username"); String password = request.getParameter("password"); //3.調用UserService的login(username,password),返回一個user對象
User user = new UserService().login(username,password); //4.判斷user是否爲空
if(user==null) { //user爲空
response.getWriter().print("用戶名和密碼不匹配"); }else { //user爲不爲空
response.getWriter().print(user.getUsername()+":歡迎回來"); } } }
DataSourseUtils.java源碼:
package com.hjh.util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class DataSourseUtils { //創建鏈接池ds
private static ComboPooledDataSource ds = new ComboPooledDataSource(); //獲取數據源
public static DataSource getDataSourse() { return ds; } //獲取鏈接
public static Connection getConnection() throws SQLException { return ds.getConnection(); } //釋放資源
public static void closeResourse(Connection conn,Statement st) { try { if(st!=null) { st.close(); }else { st = null; } } catch (SQLException e) { e.printStackTrace(); } try { if(conn!=null) { conn.close(); }else { conn = null; } } catch (SQLException e) { e.printStackTrace(); } } /**釋放資源closeResourse(conn,ps)*/
public static void closeResourse(Connection conn,PreparedStatement ps) { try { if(ps!=null) { ps.close(); }else { ps = null; } } catch (SQLException e) { e.printStackTrace(); } try { if(conn!=null) { conn.close(); }else { conn = null; } } catch (SQLException e) { e.printStackTrace(); } } /**釋放資源closeResourse(rs)*/
public static void closeResourse(ResultSet rs) { try { if(rs!=null) { rs.close(); }else { rs = null; } } catch (SQLException e) { e.printStackTrace(); } } }
c3p0-config.xml配置
<c3p0-config>
<!-- 默認配置,若是沒有指定則使用這個配置 -->
<default-config>
<!-- 基本配置 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost/hejh</property>
<property name="user">root</property>
<property name="password">root</property>
<!--擴展配置-->
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
<!-- 命名的配置 -->
<named-config name="XXX">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property>
<property name="user">root</property>
<property name="password">1234</property>
<!-- 若是池中數據鏈接不夠時一次增加多少個 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">20</property>
<property name="minPoolSize">10</property>
<property name="maxPoolSize">40</property>
<property name="maxStatements">20</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.hjh.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
index.html頁面代碼
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用戶登陸</title>
</head>
<body>
<form action="http://localhost:8080/Servlet/login" method="get"> 用戶名:<input type="text" name="username"> 密碼:<input type="password" name="password">
<input type="submit" value="login">
</form>
</body>
啓動項目,瀏覽器中輸入url:「http://localhost:8080/Servlet/login.html」回車,頁面顯示以下。用戶名密碼輸入「hjh;123」,點擊login按鈕,表單提交到"http://localhost:8080/Servlet/login",給服務器發送一個請求,url爲「http://localhost:8080/Servlet/login?username=hjh&password=123」,loginServlet類接收到用戶請求 並處理,將用戶提交的用戶名密碼和數據庫中的用戶名密碼相比較。
常見的響應頭-refresh 響應頭格式: refresh:秒數;url=跳轉的路徑 設置響應頭: response.setHeader(String key,String value);設置字符串形式的響應頭 response.addHeader(String key,String value);追加響應頭, 若以前設置設置過這個頭,則追加;若沒有設置過,則設置 設置定時刷新: response.setHeader("refresh","3;url=/Servlet/login.html");
LoginServlet優化1:定時跳轉
實現:在LoginServlet源碼中加上紅色部分代碼便可
package com.hjh.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hjh.domain.User; import com.hjh.service.UserService; public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.設置編碼
response.setContentType("text/html;charset=utf-8"); //2.接收用戶名和密碼
String username = request.getParameter("username"); String password = request.getParameter("password"); //3.調用UserService的login(username,password),返回一個user對象
User user = new UserService().login(username,password); //4.判斷user是否爲空
if(user==null) { //user爲空 response.getWriter().print("用戶名和密碼不匹配,3秒後跳轉"); //優化,定時跳轉 response.setHeader("refresh","3;url=/Servlet/login.html"); }else { //user爲不爲空
response.getWriter().print(user.getUsername()+":歡迎回來"); } } }
啓動項目,輸入錯誤的用戶名或密碼,點擊login按鈕,頁面提示「用戶名和密碼不匹配,3秒後跳轉」,3秒後跳轉到index.html頁面。
LoginServlet優化2:統計用戶登陸次數
在原loginServlet案例中,加入下面紅色部分代碼,實現打印當前用戶登陸次數的功能:
package com.hjh.servlet; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hjh.domain.User; import com.hjh.service.UserService; public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; //初始化登陸次數 @Override public void init() throws ServletException{ //獲取上下文對象 ServletContext context = getServletContext(); //初始化登陸次數爲0 context.setAttribute("count",0); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.設置編碼
response.setContentType("text/html;charset=utf-8"); //2.接收用戶名和密碼
String username = request.getParameter("username"); String password = request.getParameter("password"); //3.調用UserService的login(username,password),返回一個user對象
User user = new UserService().login(username,password); //4.判斷user是否爲空
if(user==null) { //user爲空
response.getWriter().print("用戶名和密碼不匹配,3秒後跳轉"); //優化,定時跳轉
response.setHeader("refresh","3;url=/Servlet/login.html"); }else { //user爲不爲空
response.getWriter().println(user.getUsername()+":歡迎回來"); //獲取上下文對象 ServletContext context = getServletContext(); //獲取當前登陸的次數sum Integer sum = (Integer) context.getAttribute("count"); //登陸成功了,次數自增1 sum++; //再將次數放入上下文對象中 context.setAttribute("count", sum); //獲取最新的登陸次數,打印輸出 Integer count = (Integer) context.getAttribute("count"); response.getWriter().print("登陸成功的總次數爲:"+count); } } }
serlvet總結:
servlet的體系結構:(瞭解) Servlet:接口 | GenericServlet:抽象類 | HttpServlet:抽象類 | 自定義servlet
servlet經常使用方法: void init(ServletConfig config):初始化 void service(ServletRequest request,ServletResponse response):服務 處理業務邏輯 void destroy():銷燬 ServletConfig getServletConfig() :獲取當前servlet的配置對象
GenericServlet經常使用方法:
除了service方法沒有顯示,其餘都實現了
空參的Init() 若咱們本身想對servlet進行初始化操做,重寫這個init()方法便可
HttpServlet經常使用方法:
service作了實現,把參數強轉,調用了重載的service方法
重載的service方法獲取請求的方式,根據請求方式的不一樣調用相應doXxx()方法
doGet和doPost方法
servlet生命週期:
void init(ServletConfig config):初始化 * 初始化方法 * 執行者:服務器 * 執行次數:一次 * 執行時機:默認第一次訪問的時候 void service(ServletRequest request,ServletResponse response):服務 處理業務邏輯 * 服務 * 執行者:服務器 * 執行次數:請求一次執行一次 * 執行時機:請求來的時候 void destroy():銷燬 * 銷燬 * 執行者:服務器 * 執行次數:只執行一次 * 執行時機:當servlet被移除的時候或者服務器正常關閉的時候 serlvet是單實例多線程 默認第一次訪問的時候,服務器建立servlet,並調用init實現初始化操做.並調用一次service方法 每當請求來的時候,服務器建立一個線程,調用service方法執行本身的業務邏輯 當serlvet被移除或服務器正常關閉的時候,服務器調用servlet的destroy方法實現銷燬操做.
url-pattern的配置:★ 方式1:徹底匹配 必須以"/"開始 例如: /hello /a/b/c 方式2:目錄匹配 必須"/"開始 以"*"結束 例如: /a/* /* 方式3:後綴名匹配 以"*"開始 以字符結尾 例如: *.jsp *.do *.action
優先級: 徹底匹配>目錄匹配>後綴名匹配
練習: 有以下的一些映射關係: Servlet1 映射到 /abc/* Servlet2 映射到 /* Servlet3 映射到 /abc Servlet4 映射到 *.do 問題: 當請求URL爲「/abc/a.html」,「/abc/*」和「/*」都匹配,哪一個servlet響應 Servlet引擎將調用Servlet1。 當請求URL爲「/abc」時,「/*」和「/abc」都匹配,哪一個servlet響應 Servlet引擎將調用Servlet3。 當請求URL爲「/abc/a.do」時,「/abc/*」和「*.do」都匹配,哪一個servlet響應 Servlet引擎將調用Servlet1。 當請求URL爲「/a.do」時,「/*」和「*.do」都匹配,哪一個servlet響應 Servlet引擎將調用Servlet2. 當請求URL爲「/xxx/yyy/a.do」時,「/*」和「*.do」都匹配,哪一個servlet響應 Servlet引擎將調用Servlet2。
在servlet標籤有一個子標籤 load-on-startup 做用:用來修改servlet的初始化時機 取值:正整數 值越大優先級越低
注意:
當咱們的配置文件裏面沒有指定配置的話,會查找tomcat的web.xml,
若請求咱們本身的項目處理不了,tomcat的默認的servlet會幫咱們處理信息
路徑的寫法: 相對路徑: 當前路徑 ./ 或者 什麼都不寫 上一級路徑 ../ 絕對路徑:(咱們使用) 帶主機和協議的絕對路徑(訪問站外資源) http://www.itheima.com/xxxx
http://localhost:80/day09/hello
不帶主機和協議的絕對路徑
ServletContext: 上下文 經常使用的方法: setAttribute(String key,Object value);//設置值
Object getAttribute(String key);//獲取值
removeAttribute(String key)://移除值
獲取全局管理者: getServletContext();
ServletConfig:(瞭解) servlet配置對象 做用: 1.獲取當前servlet的名稱 2.獲取當前servlet的初始化參數 3.獲取全局管理者 方法: String getServletName():獲取當前servlet的名稱(web.xml配置的servlet-name) String getInitParameter(String key):經過名稱獲取指定的參數值 Enumeration getInitParameterNames() :獲取全部的參數名稱 初始化參數是放在 web.xml文件 servlet標籤下子標籤 init-param ★getServletContext():獲取全局管理者 servletconfig是由服務器建立的,在建立servlet的同時也建立了它,經過servlet的init(ServletConfig config)將config對象 傳遞給servlet,由servlet的getServletConfig方法獲取
ServletConfig小練習:
web.xml配置:
<servlet>
<servlet-name>SConfigServlet</servlet-name>
<servlet-class>com.hjh.servlet.SConfigServlet</servlet-class>
<init-param> <param-name>age</param-name> <param-value>18</param-value> </init-param> <init-param> <param-name>hjh</param-name> <param-value>123</param-value> </init-param>
</servlet>
<servlet-mapping>
<servlet-name>SConfigServlet</servlet-name>
<url-pattern>/config</url-pattern>
</servlet-mapping>
package com.hjh.servlet; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SConfigServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取ServletConfig對象
ServletConfig config = getServletConfig(); //獲取servlet的名稱
String servletName = config.getServletName(); System.out.println("servletName的名稱是:"+servletName); //獲取初始化參數,獲取單一的值
String age = config.getInitParameter("age"); System.out.println("age的值是:"+age); System.out.println("------------------------------------------------------------"); //獲取全部的初始化參數
Enumeration<String> initParameterNames = config.getInitParameterNames(); while(initParameterNames.hasMoreElements()) { String name = initParameterNames.nextElement(); System.out.println("name:"+config.getInitParameter(name)); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
eclipse中console輸出爲:
servletName的名稱是:SConfigServlet age的值是:18
------------------------------------------------------------ name:123 name:18
ServletContext上下文
一個項目的引用.表明了當前項目. 當項目啓動的時候,服務器爲每個web項目建立一個servletcontext對象. 當項目被移除的時候或者服務器關閉的時候servletcontext銷燬 做用: 1.獲取全局的初始化參數 2.共享資源(xxxAttribute) 3.獲取文件資源 4.其餘操做 獲取servletcontext: 方式1:瞭解 getServletConfig().getServletContext() 方式2: getServletContext() 經常使用方法: 1.瞭解 String getInitParameter(String key):經過名稱獲取指定的參數值 Enumeration getInitParameterNames() :獲取全部的參數名稱 在根標籤下有一個 context-param子標籤 用來存放初始化參數 <context-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</context-param>
2.xxxAttribute 3. String getRealPath(String path):獲取文件部署到tomcat上的真實路徑(帶tomcat路徑) getRealPath("/"):D:\javaTools\apache-tomcat-7.0.52\webapps\day09\ InputStream getResourceAsStream(String path):以流的形式返回一個文件 4.獲取文件的mime類型 大類型/小類型 String getMimeType(String 文件名稱)
web.xml配置:
SContextServlet.java源碼:
package com.hjh.servlet; import java.io.IOException; import java.io.InputStream; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SContextServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.獲取上下文對象
ServletContext context = getServletContext(); //2.獲取全局初始化參數
String encoding = context.getInitParameter("encoding"); System.out.println("encoding:"+encoding);//encoding:utf-8 //3.獲取文件真實目錄
String contextPath = context.getContextPath(); System.out.println("contextPath:"+contextPath);//contextPath:/Servlet
String realPath = context.getRealPath("/c3p0-config.xml"); System.out.println("realPath:"+realPath);//realPath:D:\tomcat-9.0\webapps\Servlet\c3p0-config.xml //4.以流的形式返回一個文件
InputStream is = context.getResourceAsStream("/c3p0-config.xml"); System.out.println(is);//null //5.獲取文件的mime類型
String mimeType = context.getMimeType("1.jpg"); System.out.println(mimeType); //image/jpeg
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
獲取文件的路徑: 經過類加載器獲取文件:2.txt 放在classes目錄下不管是java項目仍是web項目均可以 類.class.getClassLoader().getResource("2.txt").getPath()
web.xml配置
<servlet>
<servlet-name>PathServlet</servlet-name>
<servlet-class>com.hjh.servlet.PathServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PathServlet</servlet-name>
<url-pattern>/path</url-pattern>
</servlet-mapping>
PathServlet.java源碼
package com.hjh.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PathServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = PathServlet.class.getClassLoader().getResource("c3p0-config.xml").getPath(); System.out.println(path);///D:/tomcat-9.0/webapps/Servlet/WEB-INF/classes/c3p0-config.xml
String path2 = PathServlet.class.getClassLoader().getResource("/c3p0-config.xml").getPath(); System.out.println(path2);///D:/tomcat-9.0/webapps/Servlet/WEB-INF/classes/c3p0-config.xml
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }