1.手寫 開發servlet步驟:
1.在tomcat中新建一個web應用,然後在web應用中新建一個WEB-INF/classes目錄。
2.在classes目錄中新建一個FirstServlet:
package cn.itcast;
import java.io.*;
import javax.servlet.*;
public class FirstServlet extends GenericServlet
{
public void service(ServletRequest req,ServletResponse res)throws ServletException,java.io.IOException
{
OutputStream out = res.getOutputStream();
out.write("hello servlet!".getBytes());
}
}
3.set classpath=%classpath%;C:\apache-tomcat-8.5.4\lib\servlet-api.jar,然後編譯servlet。
4.在WEB-INF中新建web.xml文件,配置servlet對外訪問路徑。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>cn.itcast.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
</web-app>
5.啓動tomcat,ie訪問。
2.servlet的調用過程 和 生命週期:
servlet 的生命週期:
servlet對象在用戶第一次訪問的時候創建,生命週期開始。然後init方法會執行對象初始化。
servlet對象一直駐留在內存中響應後續的請求。客戶端的每次請求會執行service方法。servlet被摧毀的時候destroy方法會被執行。
web服務器停止或者wen應用被刪除的時候,servlet會被摧毀,生命週期結束。
servlet運行過程:
2.使用Eclipse開發servlet
①Servlet接口的實現類:HttpServlet
3.Servlet開發的一些重要細節:
①servlet的映射
②servlet的多映射
③servlet的多映射的通配符細節
④Servlet對象在客戶端訪問web服務器時創建一次,init方法只調用一次
⑤在web應用的web.xml元素配置,對象就在web服務器啓動時就創建。
⑥tomcat服務器有自己配置缺省servlet
⑦多個客戶端併發訪問一個servlet時容易發生線程安全問題
4.web服務器會給servlet多個對象:
ServletConfig,ServletContext,request,response,Cookie,Session。等等
5.ServletConfig對象:在web應用的配置文件web.xml中配置必要的數據。
配置:
獲取:
6.ServletContext對象:
ServletContext方法的應用:
context域對象(request域,session域,page域)
①setAttribute(),getAttribute():實現servlet之間的數據共享:
/*
ServletContext域:
1.這時一個容器
2.servletcontext域這句話說明了這個容器作用範圍,也就是應用程序範圍。
*/
//通過servletcontext實現Demo4和Demo5的數據共享
public class ServletDemo4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data = "aaa";
this.getServletContext().setAttribute("data", data);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class ServletDemo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String value = (String)this.getServletContext().getAttribute("data");
System.out.println(value);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
②獲取web應用的初始化參數
web.xml:
<context-param>
<param-name>data</param-name>
<param-value>xxxx</param-value>
</context-param>
//獲取web應用的初始化參數
public class ServletDemo6 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.getServletContext().getInitParameter("data");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
③實現servlet轉發:servlet不適合做數據輸出,轉發給JSP處理。
轉發:幫你找別人處理請求,客戶端請求一次
重定向:告訴你該找誰重發請求,客戶端請求兩次。
如果用servletcontext帶數據來轉發,可能會出現多個servlet對象覆蓋原有的數據的安全問題:
//通過ServletContext實現請求轉發
public class ServletDemo6 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data = "abacsbd";
//數據帶給1.jsp(不能通過context域,要通過request域)
this.getServletContext().setAttribute("data", data);
//轉發對象:
RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/1.jsp");
rd.forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
1.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP '1.jsp' starting page</title>
</head>
<body>
<font color="red">
<%
String data = (String) application.getAttribute("data");
out.write(data);
%>
</font>
</body>
</html>
④:利用ServletContext對象讀取資源文件
得到文件路徑
讀取資源文件的三種方式
.properties文件
ServletContext對象生命週期:web服務器啓動時產生,有多少個應用,就有多少個ServletContext對象。停止服務器或者移除web應用,則ServletContext對象被銷燬。
//通過servletcontext讀取資源文件
public class ServletDemo7 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// test1(); //標準方式
test2(); //傳統方式
}
//讀取資源文件,注意問題:一般不用傳統方式去讀取,相對路徑問題,傳統方式讀的相對路徑是jvm,即tomcat的啓動目錄。
private void test2() throws IOException {
//獲取絕對路徑(好處是 可以獲得資源的名稱,下載的時候需要)
String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
String filename = path.substring(path.lastIndexOf("\\")+1);
System.out.println(filename);
//這個時候可以用傳統方式讀取
FileInputStream in = new FileInputStream(path);
Properties props = new Properties();
props.load(in);
String url = props.getProperty("url");
String username = props.getProperty("username");
String password = props.getProperty("password");
System.out.println(url);
}
public void test1() throws IOException {
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties props = new Properties();
props.load(in);
String url = props.getProperty("url");
String username = props.getProperty("username");
String password = props.getProperty("password");
System.out.println(url);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
處理數據一般放在dao包裏:
web應用中的普通Java程序如何讀取資源文件。
//Servlet調用其他其他程序,在其他程序中如何讀取資源文件(通過類加載器)
public class ServletDemo8 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
UserDao dao = new UserDao();
dao.update();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//如果讀取資源文件的程序部是servlet的話,就只能通過類裝載器去讀了。
//①文件不能太大
//②類裝載器只裝再一次,所以裝載一次後不再裝載,即使後來對資源有改動
//②的解決辦法:獲取絕對路徑,傳統方法讀取
public class UserDao {
/* private static Properties dbconfig = new Properties();
static {
// 得到類的加載器
try{
ClassLoader cl= UserDao.class.getClassLoader();
InputStream in = cl.getResourceAsStream(
"db.properties");
dbconfig.load(in);
}catch(Exception e){
throw new ExceptionInInitializerError(e);
}
}*/
//通過類裝載的方式得到資源文件的位置,再通過傳統方式讀取資源文件的數據,這樣可以讀取到更新後的數據。
public void update() throws IOException {
/* //以下代碼雖然可以讀取資源文件的的數據,但是無法獲取更新後的數據。
String url = dbconfig.getProperty("url");
String username = dbconfig.getProperty("username");
String password = dbconfig.getProperty("password");
System.out.println(url);*/
String path = UserDao.class.getClassLoader().getResource("db.properties").getPath();
FileInputStream in = new FileInputStream(path);
Properties dbconfig = new Properties();
dbconfig.load(in);
System.out.println(dbconfig.getProperty("url"));
}
public void find(){
}
}