聯想小新 Air 14/15 2021 酷睿版配置公佈:i5-1155G7+16GB 記憶體,配備全功能 USB-C 介面
Servlet是sun公司開發動態web的一門技術
Sun在這些API中提供一個介面叫Servlet ,如果想開發一個Servlet程式,只需要完成兩個步驟
-
-
把開發好的java類部署到web伺服器中
把實現了servlet介面的java程式叫做servlet
2、關於Maven父子工程的理解
父專案中會有
<modules> <module>servlet-01</module> </modules>
子專案中會有
<parent> <artifactId>javaweb-servlet</artifactId> <groupId>com.cheng</groupId> <version>1.0-SNAPSHOT</version> </parent>
3、Maven環境優化
1、修改web.xml為最新的 (內容是tomcat的webapps/root/WEB-INF/web.xml)
2、將maven的結構搭建完整
4、編寫一個servlet程式
1、編寫一個普通類
2、實現Servlet嗟闊,這裡我們直接繼承HttpServlet
public class HelloServlet extends HttpServlet { //由於get或者post只是請求實現的不同方式,可以相互呼叫,業務邏輯都一樣 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer= resp.getWriter();//響應流 writer.print("hello,servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
5、編寫Servlet的對映
<!--註冊Servlet--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.cheng.servlet.HelloServlet</servlet-class> </servlet> <!--Servlet的請求路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
7、啟動測試
<!--在build中配置resoureces,來防止我們資源匯出失效的問題--> <build> <resources> <resource> <directory>src/main/resources/</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
2、一個servlet可以指定多個對映路徑
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping>
3、一個servlet可以指定通用對映路徑
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
4、預設請求路徑
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping
<!--可以自定義字尾實現請求對映 注意:*前面不能加對映的路徑 比如 hello/sdsds.miaomiao--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.miaomiao</url-pattern> </servlet-mapping>
指定了固有的對映路徑優先順序最高,如果找不到就會走預設的處理請求
<!--404--> <servlet> <servlet-name>error</servlet-name> <servlet-class>com.cheng.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class ErrorServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); PrintWriter writer = resp.getWriter(); writer.print("<h1>404</h1>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // this.getInitParameter();//初始化引數 // this.getServletConfig();//Servlet配置 // this.getServletContext();//Servlet上下文 ServletContext context = this.getServletContext(); String username="喵喵";//資料 context.setAttribute("username",username);//將一個數據儲存在ServletContext中,名字為:username,,值為username System.out.println("Hello"); } }
public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String username = (String) context.getAttribute("username"); resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); resp.getWriter().print("名字"+username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.cheng.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>getc</servlet-name> <servlet-class>com.cheng.servlet.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getc</servlet-name> <url-pattern>/getc</url-pattern> </servlet-mapping>
<context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); resp.getWriter().print(url); }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); System.out.println("進入了ServletDemo04"); //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//轉發的請求路徑 //requestDispatcher.forward(req,resp);//呼叫forward實現請求轉發 context.getRequestDispatcher("/gp").forward(req,resp); }
propertie
-
-
在resources目錄下新建properties
發現都被打包到了同一個路徑下:classes ,俗稱這個路徑為類路徑
思路:需要一個檔案流
username=root
password=1235465
public class ServletDemo05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is= this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Properties prop = new Properties(); prop.load(is); String user = prop.getProperty("username"); String pwd = prop.getProperty("password"); resp.getWriter().print(user+":"+pwd); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
訪問測試即可
web伺服器接收到客戶端的http請求,針對這個請求,分別建立一個代表請求的HttpServletRequest物件,代表響應的一個HttpServletResponse
如果要獲取客戶端請求過來的引數,找HttpServletRequest
如果要給客戶端響應一些資訊,找HttpServletResponse
向瀏覽器傳送資料的方法
ServletOutputStream getOutputStream() throws IOException; PrintWriter getWriter() throws IOException;
向瀏覽器傳送響應頭的方法
void setCharacterEncoding(String var1); void setContentLength(int var1); void setContentLengthLong(long var1); void setContentType(String var1); void setDateHeader(String var1, long var2); void addDateHeader(String var1, long var2); void setHeader(String var1, String var2); void addHeader(String var1, String var2); void setIntHeader(String var1, int var2); void addIntHeader(String var1, int var2);
響應的狀態碼
int SC_CONTINUE = 100; int SC_SWITCHING_PROTOCOLS = 101; int SC_OK = 200; int SC_CREATED = 201; int SC_ACCEPTED = 202; int SC_NON_AUTHORITATIVE_INFORMATION = 203; int SC_NO_CONTENT = 204; int SC_RESET_CONTENT = 205; int SC_PARTIAL_CONTENT = 206; int SC_MULTIPLE_CHOICES = 300; int SC_MOVED_PERMANENTLY = 301; int SC_MOVED_TEMPORARILY = 302; int SC_FOUND = 302; int SC_SEE_OTHER = 303; int SC_NOT_MODIFIED = 304; int SC_USE_PROXY = 305; int SC_TEMPORARY_REDIRECT = 307; int SC_BAD_REQUEST = 400; int SC_UNAUTHORIZED = 401; int SC_PAYMENT_REQUIRED = 402; int SC_FORBIDDEN = 403; int SC_NOT_FOUND = 404; int SC_METHOD_NOT_ALLOWED = 405; int SC_NOT_ACCEPTABLE = 406; int SC_PROXY_AUTHENTICATION_REQUIRED = 407; int SC_REQUEST_TIMEOUT = 408; int SC_CONFLICT = 409; int SC_GONE = 410; int SC_LENGTH_REQUIRED = 411; int SC_PRECONDITION_FAILED = 412; int SC_REQUEST_ENTITY_TOO_LARGE = 413; int SC_REQUEST_URI_TOO_LONG = 414; int SC_UNSUPPORTED_MEDIA_TYPE = 415; int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; int SC_EXPECTATION_FAILED = 417; int SC_INTERNAL_SERVER_ERROR = 500; int SC_NOT_IMPLEMENTED = 501; int SC_BAD_GATEWAY = 502; int SC_SERVICE_UNAVAILABLE = 503; int SC_GATEWAY_TIMEOUT = 504; int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
1、向瀏覽器傳送訊息
2、下載檔案
import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; public class FileServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //獲取下載檔案的路徑 String realPath = "F:\\JavaProjects\\javaweb-servlet\\response\\src\\main\\resources\\test1.jpg"; System.out.println("下載檔案的路徑"+realPath); //下載的檔名 String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); //設定讓瀏覽器能夠支援下載我們需要的東西(web下載檔案的頭訊息) resp.setHeader("Content-Disposition","attachment;filename"+URLEncoder.encode(fileName,"UTF-8")); //獲取下載檔案的輸入流 FileInputStream in = new FileInputStream(realPath); //建立緩衝區 int len=0; byte[] buffer = new byte[1024]; //獲取outputStream物件 ServletOutputStream out = resp.getOutputStream(); //將FileoutputStream流寫入到buffer緩衝區,使用outputstream將緩衝區中的資料輸出到客戶端 while((len=in.read(buffer))>0){ out.write(buffer,0,len); } //關閉流 in.close(); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } }
3、驗證碼功能
import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; public class ImageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //如何讓瀏覽器5秒自動重新整理以此 resp.setHeader("refresh","3"); //在記憶體中建立一個圖片 BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_3BYTE_BGR); //得到圖片 Graphics2D g = (Graphics2D) image.getGraphics();//筆 //設定圖片的背景顏色 g.setColor(Color.white); g.fillRect(0,0,80,20); //給圖片寫資料 g.setColor(Color.blue); g.setFont(new Font(null,Font.BOLD,20)); g.drawString(makeNum(),0,20); //告訴瀏覽器這個請求用圖片的方式開啟 resp.setContentType("image/jpeg"); //網站存在快取,不讓瀏覽器快取 resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); //把圖片寫給瀏覽器 ImageIO.write(image,"jpg",resp.getOutputStream()); } //生成隨機數 private String makeNum(){ Random random = new Random(); String num = random.nextInt(99999999)+""; StringBuffer sb = new StringBuffer(); for(int i=0;i<7-num.length();i++){ sb.append("0"); } num= sb.toString()+num; return num; } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } }
一個web資源收到客戶端請求後,它會通知客戶端去訪問另外一個web資源,這個過程叫重定向
void sendRedirect(String var1) throws IOException;
測試
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // resp.setHeader("Location","/img"); // resp.setStatus(302); resp.sendRedirect("/img"); }
重定向和轉發的區別?
-
相同點: 頁面都會實現跳轉
不同點:
-
請求轉發的時候,url不會產生變化
-
重定向的時候,url位址列會發生變化
會話:使用者開啟一個瀏覽器,點選了很多超連結,訪問多個web資源,關閉瀏覽器,這個過程可以稱之為會話
1、伺服器給客戶端一個信件,客戶端下次訪問伺服器帶上信件就可以了,cookie
2、伺服器登記你來過,下次你來的時候我來匹配你,session
cookie
客戶端技術(響應,請求)
1、從請求中拿到cookie資訊
2、伺服器響應給客戶端cookie
Cookie[] cookies = req.getCookies();//獲得cookie cookie.getName();//獲得cookie中的key cookie.getValue();//獲得cookie中的value new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一個cookie cookie.setMaxAge(24*60*60);//設定cookie的有效期 resp.addCookie(cookie);//響應給客戶端一個cookie
//儲存使用者上一次訪問的時間 public class CookieDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); PrintWriter out = resp.getWriter(); //cookie ,伺服器端從客戶端獲取 Cookie[] cookies = req.getCookies();//返回陣列,說明cookie可能存在多個 //判斷cookie是否存在 if(cookies!=null){ //如果存在 out.write("您上一次訪問的時間是:"); for(int i=0;i<cookies.length;i++){ Cookie cookie= cookies[i]; //獲取cookie的名字 if(cookie.getName().equals("lastLoginTime")){ //獲取cookie中的值 long lastLoginTime = Long.parseLong(cookie.getValue()); Date date = new Date(lastLoginTime); out.write(date.toLocaleString()); } } }else{ out.write("這是您第一次訪問本站"); } //伺服器給客戶端響應一個cookie Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+""); //cookie有效期為1天 cookie.setMaxAge(24*60*60); resp.addCookie(cookie); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } }
cookie一般會儲存在本地的使用者目錄下appdata
session
-
伺服器會給每一個使用者(瀏覽器)建立一個session物件
-
一個session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個session就存在
-
使用者登入後,整個網站它都可以訪問
session和cookie的區別
-
cookie是把使用者的資料寫給使用者的瀏覽器,瀏覽器儲存(可以儲存多個)
-
session把使用者的資料寫到使用者獨佔session中,伺服器端儲存(儲存重要的資訊,減少伺服器資源的浪費)
-
session物件由伺服器建立
使用場景:
-
儲存一個登入使用者的資訊
-
購物車資訊
-
在整個網站中經常使用的資料,我們將它儲存在session中
使用session
public class SessionDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解決亂碼問題 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=utf-8"); //得到session HttpSession session = req.getSession(); //給session中存東西 session.setAttribute("name","喵喵"); //獲取session的id String sessionId = session.getId(); //判斷session是不是新建立的 if(session.isNew()){ resp.getWriter().write("session建立成功,ID:"+sessionId); }else { resp.getWriter().write("session已經在伺服器中存在,ID:"+sessionId); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } } //得到session HttpSession session= req.getSession(); Person person = session.getAttribute("name"); System.out.println( person.toString()); //手動登出session HttpSession session= req.getSession(); session.removeAttribute("name"); session.invalidate();
會話自動過期 web.xml
<!--設定session預設的失效時間--> <session-config> <!--15分鐘後session自動失效,以分鐘為單位--> <session-timeout>15</session-timeout> </session-config>
瀏覽器向伺服器傳送請求,不管訪問什麼資源,其實都是在訪問servlet
jsp最終也會被轉換成一個java類
<%--JSP表示式 作用:用來將程式的輸出,輸出到客戶端--%> <%= new java.util.Date()%> <hr> <%--jsp指令碼片段--%> <% int sum=0; for (int i = 0; i < 100; i++) { sum+=i; } out.print("<h1>Sum="+sum+"</h1>"); %> <%--在程式碼中嵌入HTML元素--%> <% for (int i = 0; i < 5; i++) { %> <h1>hello</h1> <% } %> <hr> <%--jsp宣告--%> <%! static { System.out.println("loading servlet"); } private int globalVar=0; public void miao(){ System.out.println("進入了方法miao"); } %>
jsp宣告會被編譯到JSP生成的java的類中,其他就會被生成到jspService方法中
在jsp中嵌入java程式碼即可
jsp的註釋,不會在客戶端顯示,html就會
9大內建物件
PageContext 存東西
Request 存東西
Response
Session 存東西
Application [ServletContext ] 存東西
config [ServletConfig]
out
page 不用
exception
pageContext.setAttribute("name1","喵喵1號");//儲存的資料只在一個頁面中有效 request.setAttribute("name2","喵喵2號");//儲存的資料只在一次請求中有效,請求轉發會攜帶這個資料 session.setAttribute("name2","喵喵2號");//儲存的資料只在一次會話中有效,從開啟瀏覽器到關閉瀏覽器 application.setAttribute("name2","喵喵2號");//儲存的資料只在伺服器中有效,從開啟伺服器到關閉伺服器
request:客戶端向伺服器傳送請求,產生的資料,使用者看完就沒用了。比如新聞
session:客戶端向伺服器傳送請求,產生的資料,使用者用完一會兒還有用,比如購物車
application:客戶端向伺服器傳送請求,產生的資料,一個使用者用完了,其他使用者還可以使用,比如聊天資料
<!--jstl表示式的依賴--> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency>
EL表示式: ${}
-
獲取資料
-
執行運算
-
獲取web開發的常用物件
JSP標籤
<jsp:forward page="/jsptag2.jsp"> <jsp:param name="name" value="miaomiao"></jsp:param>
JSTL標籤
<%--引入JSTL核心標籤庫,我們才能使用JSTL標籤--%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <form action="jsptag2.jsp" method="get"> <%--EL表示式獲取表單中的資料--%> <input type="text" name="username" value="${param.username}"> <input type="submit" value="登入"> <c:if test="${param.username='admin'}" var="isAdmin"> <c out value="管理員歡迎您"/> </c:if> <c: out value="${isAdmin}"/>
實體類
-
JavaBean有特定的寫法
-
必須要有一個無參構造
-
屬性必須私有化
-
必須有對應的get/set方法
一般用來和資料庫的欄位作對映