1、配置Tomcat服務(wù)器
一、Servlet 2.0
1、書寫servlet程序
import javax.servlet.*;
import java.io.IOException;
public class MyServletDemo implements Servlet {
@Override
/**
* Servlet 初始化的時(shí)候執(zhí)行,只會執(zhí)行一次
*/
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("=======init=======");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
/**
* Servlet 請求的時(shí)候執(zhí)行,會執(zhí)行多次
*/
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("======hello service=====");
}
@Override
public String getServletInfo() {
return null;
}
@Override
/**
* Servlet 關(guān)閉的時(shí)候執(zhí)行,會執(zhí)行一次
*/
public void destroy() {
}
}
2、配置WEB-INF下面的web.xml(配置路由)
<?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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>com.example.demoJJ.servlet.MyServletDemo</servlet-class>
<!--
指定Servlet的創(chuàng)建時(shí)機(jī):
1. 第一次被訪問時(shí),創(chuàng)建。load-on-startup 配置的值為負(fù)數(shù)。
2. 在服務(wù)器啟動時(shí)創(chuàng)建。load-on-startup 配置為0或者正數(shù)
3. 默認(rèn)為負(fù)數(shù)
-->
<load-on-startup>-1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
</web-app>
3、解析
當(dāng)你在瀏覽器中輸入IP端口的時(shí)候,tomcat會對你的url進(jìn)行解析,此時(shí)會有一個(gè)
/demo1的路由,tomcat會在web.xml 中進(jìn)行解析,剛好會有一個(gè)幾個(gè)/demo1的路由與之對應(yīng)。此時(shí)找到servlet-name,通過servlet-name會找到全類名的類,此時(shí)tomcat通過反射找到方法去執(zhí)行(Class.forName() 加入字節(jié)碼,newInstance產(chǎn)生實(shí)例)。
4、Servlet的生命周期
- 被創(chuàng)建:執(zhí)行
init方法,只會執(zhí)行一次。 - 提供服務(wù):執(zhí)行
service方法,執(zhí)行多次。 - 被銷毀:執(zhí)行
destory方法,執(zhí)行一次。(正常關(guān)閉的時(shí)候會執(zhí)行)
5、總結(jié)
-
Servlet是單例的,會存在線程安全問題,所以盡量不要定義成員變量。
一、Servlet 3.0的介紹
1、使用注解配置Servlet
介紹:
Servlet3.0是向下兼容的,在Servlet 3.0中支持注解的方式配置應(yīng)用。當(dāng)只有urlPatterns的時(shí)候可以不寫。
package com.example.demoJJ.servlet;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet(urlPatterns = "/demo2")
public class MySev3 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet 3.0");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
2、使用HttpServlet進(jìn)行進(jìn)行書寫程序
package com.example.demoJJ;
import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
private String message;
public void init() {
message = "Hello World!";
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>" + message + "</h1>");
out.println("</body></html>");
}
public void destroy() {
}
}
三、Request對象的部分知識點(diǎn)
1、請求的轉(zhuǎn)發(fā)與編碼的設(shè)置
request.setCharacterEncoding("UTF-8"); // 設(shè)置編碼
request.getRequestDispatcher("/demo1").forward(request, response); // 請求轉(zhuǎn)發(fā)
2、設(shè)置屬性,獲取屬性【共享數(shù)據(jù)】
request.setAttribute("name", "erik");
request.getAttribute("name");
四、一個(gè)小demo
1、工具類的編寫
package com.example.demoLogin.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtil {
private static DataSource ds;
private static String driver;
static {
// 讀取配置文件
InputStream resourceAsStream = JdbcUtil.class.getClassLoader().getResourceAsStream("druid.properties");
Properties properties = new Properties();
try {
properties.load(resourceAsStream);
driver = properties.getProperty("driverClassName");
// 導(dǎo)入驅(qū)動
Class.forName(driver);
// 初始化數(shù)據(jù)庫連接池
ds = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取數(shù)據(jù)源
*
* @return
*/
public static DataSource getDatasource() {
return ds;
}
/**
* 獲取連接池對象
*
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
2、實(shí)體類
package com.example.demoLogin.doman;
/**
*
*/
public class User {
private int id;
private String name;
private String password;
public User() {
}
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
3、操作類
package com.example.demoLogin.dao;
import com.example.demoLogin.doman.User;
import com.example.demoLogin.util.JdbcUtil;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.sql.SQLException;
public class UserDao {
/**
* 獲取template
*/
private JdbcTemplate template = new JdbcTemplate(JdbcUtil.getDatasource());
/**
* 獲取用戶
*
* @param loginUser
* @return
* @throws SQLException
*/
public User getUserById(User loginUser) {
try {
String name = loginUser.getName();
String password = loginUser.getPassword();
String sql = "SELECT * FROM USER WHERE name = ? and password = ?";
return template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), name, password);
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
}
4、Servlet類
package com.example.demoLogin.servlet;
import com.example.demoLogin.doman.User;
import javax.servlet.ServletException;
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.PrintWriter;
@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
// 獲取屬性
User user = (User) req.getAttribute("user");
PrintWriter writer = resp.getWriter();
writer.write("歡迎:" + user.getName() + "登錄成功!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.example.demoLogin.servlet;
import com.example.demoLogin.dao.UserDao;
import com.example.demoLogin.doman.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
// 獲取請求參數(shù)
String name = req.getParameter("name");
String password = req.getParameter("password");
User user = new User();
user.setName(name);
user.setPassword(password);
System.out.println(user);
User user1 = new UserDao().getUserById(user);
if (user1 == null) {
// 失敗
req.getRequestDispatcher("/failServlet").forward(req, resp);
} else {
// 成功
req.setAttribute("user", user1);
req.getRequestDispatcher("/successServlet").forward(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.example.demoLogin.servlet;
import javax.servlet.ServletException;
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.PrintWriter;
@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("登錄失敗了");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
5、html展示
<%--
Created by IntelliJ IDEA.
User: Erik.Zhou
Date: 2022/2/17
Time: 11:36
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/demoLogin_war_exploded/login" method="get">
用戶名: <input type="text" name="name" placeholder="輸入用戶名!">
密碼: <input type="password" name="password" placeholder="輸入密碼!">
<button type="submit">登錄</button>
</form>
</body>
</html>
6、目錄結(jié)構(gòu)

7、狀態(tài)碼
分類:
- 1xx:服務(wù)器就接收客戶消息,但沒有接收完成,等待一段時(shí)間后,發(fā)送1xx狀態(tài)碼。
- 2xx:成功。代表:200
- 3xx:重定向。代表:302(重定向)【resp.sendRedirect("路徑"); 】。304(訪問緩存)
- 4xx:客戶端錯(cuò)誤。404(資源或者頁面不存在)。405 請求方式和對應(yīng)的方法不存在。403一般用于鑒權(quán)。
- 5xx:服務(wù)端錯(cuò)誤。500(服務(wù)器內(nèi)部異常)
8、響應(yīng)數(shù)據(jù)
- 響應(yīng)頭:
- content-type // resp.setContentType("text/html;charset=utf-8"); 設(shè)置編碼
9、重定向和轉(zhuǎn)發(fā)的區(qū)別:
重定向:
- 地址欄發(fā)生變化。
- 重定向可以訪問其他站點(diǎn)(服務(wù)器)的資源
- 重定向是兩次請求。不能使用request對象來共享數(shù)據(jù)
轉(zhuǎn)發(fā)的特點(diǎn): - 轉(zhuǎn)發(fā)地址欄路徑不變
- 轉(zhuǎn)發(fā)只能訪問當(dāng)前服務(wù)器下的資源
- 轉(zhuǎn)發(fā)是一次請求,能使用request對象來共享數(shù)據(jù)。
10、簡單的驗(yàn)證碼的使用:
package com.example.demoLogin.servlet;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet(name = "ImgServlet", value = "/ImgServlet")
public class ImgServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 100;
int height = 50;
// 1、創(chuàng)建一個(gè)對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 2、美化圖片
Graphics graphics = image.getGraphics();
graphics.setColor(Color.pink);
graphics.fillRect(0, 0, width, height);
graphics.setColor(Color.blue);
graphics.drawRect(0, 0, width - 1, height - 1);
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
for (int i1 = 0; i1 < 4; i1++) {
int i = random.nextInt(str.length());
graphics.drawString(str.charAt(i) + "", width / 5 * i1, height / 2);
}
// 畫干擾線
for (int i = 0; i < 10; i++) {
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
graphics.drawLine(x1, y1, x2, y2);
}
// 3、將圖片保存到頁面
ImageIO.write(image, "jpg", response.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
11、資源的處理:[文件下載]
// 獲取參數(shù)
String filename = req.getParameter("filename");
// 獲取預(yù)發(fā)布
ServletContext context = req.getServletContext();
// 獲取真實(shí)路徑
String realPath = context.getRealPath(filename);
// 獲取輸入流對象
FileInputStream inputStream = new FileInputStream(realPath);
// 獲取類型
String mimeType = context.getMimeType(filename);
// 設(shè)置response響應(yīng)頭
// 1、設(shè)置響應(yīng)頭類型:content-type
resp.setHeader("content-type", mimeType);
resp.setHeader("content-disposition", "attachment;filename=" + filename);
// 將字節(jié)流寫到輸出流中
ServletOutputStream outputStream = resp.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
// 關(guān)閉流對象
inputStream.close();
outputStream.close();
// 可能會初選中文的亂碼問題,可以針對不同瀏覽器設(shè)置不同的頭信息處理
12、Cookie的快速入門
// 創(chuàng)建cookie
Cookie cookie1 = new Cookie("", "");
cookie1.setMaxAge(100); // 設(shè)置cookie的時(shí)間。正數(shù):存活的秒數(shù)。0代表刪除。默認(rèn)值為負(fù)數(shù),關(guān)閉即刪除
// cookie.setPath("/"); // 共享cookie設(shè)置cookie 的范圍,共享
// cookie.setDomain(".baidu.com");
resp.addCookie(cookie1);
// 獲取cookie
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
System.out.println(cookie.getName());
}
}
13、Session的快速入門
session存儲在服務(wù)器端,他的實(shí)現(xiàn)是基于cookie的,當(dāng)?shù)谝淮握埱蟮臅r(shí)候,服務(wù)器端會set-cookie,一個(gè)值為:JSESSIONID的對象,后期客戶端會通過這個(gè)請求頭來向后端請求,從而保證了session的一致性。
細(xì)節(jié):
- 當(dāng)客戶端關(guān)閉后,服務(wù)器不關(guān)閉,再次獲取session是否是同一個(gè)?
- 默認(rèn)情況下不是。
- 如果需要是同一個(gè)則可以創(chuàng)建cookie,鍵為:JSESSION,設(shè)置最大存活時(shí)間,讓cookie持久化存活。
// 讓瀏覽器關(guān)閉后仍然是一個(gè)session。
HttpSession session = req.getSession();
Cookie jsessionid = new Cookie("JSESSIONID", session.getId());
jsessionid.setMaxAge(60 * 60);
- 客戶端不關(guān)閉,服務(wù)器關(guān)閉后,再次獲取的session是同一個(gè)嘛?【tomcat做了】
- 不是同一個(gè),但是要群數(shù)據(jù)不丟失。
- session 的鈍化
- 在服務(wù)器正常關(guān)閉之前,將session對象序列號到硬盤上
- session的活化
- 在服務(wù)器啟動后,將session文件轉(zhuǎn)化為內(nèi)存中的session對象即可。
- session什么時(shí)候被銷毀?
- 服務(wù)器關(guān)閉
- session對象調(diào)用invalidate()。
- session默認(rèn)的失效時(shí)間為 30 分鐘?!緒eb.xml中進(jìn)行配置】
14、JSP的快速入門
- 指令:
- 作用:用戶配置JSP頁面,導(dǎo)入資源文件
- 格式:
<%@ 指令名稱 屬性名1=屬性值 屬性名2=屬性值2 ....%> 如:<%@ page import="java.net.URLDecoder" %> - 分類:
- page:配置JSP頁面的。
<%@ page import="java.net.URLDecoder" %>。 - include:完成包含。導(dǎo)入頁面的資源文件。如:
公共頭部或者公共尾部。 - taglib:導(dǎo)入資源。
- page:配置JSP頁面的。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- 注釋:
<%-- 注釋內(nèi)容 --%> - 在jsp頁面中不需要創(chuàng)建,直接使用的對象一共有9個(gè):
| 變量名 | 真實(shí)類型 | 作用 |
|---|---|---|
| pageContext | PageContext | 當(dāng)前頁面共享數(shù)據(jù) |
| request | HttpServketRequest | 一次請求訪問的多個(gè)資源 |
| session | HTTPSession | 一次會話的多個(gè)請求間 |
| application | ServletContext | 所有用戶共享的數(shù)據(jù) |
| response | HttpServletResponse | 響應(yīng)對象 |
| page | Object | 當(dāng)前頁面的對象 |
| out | JSPWrite | 輸出對象,可以把數(shù)據(jù)輸出到頁面上 |
| config | ServletConfig | Servlet的配置對象 |
| exception | Throwable | :只有當(dāng)isErrorPage為true的時(shí)候才能使用。 |
- 表達(dá)式
<%! %> // 解析為:類變量
<%= "erik" %> // 輸出到頁面
<% %> // 局部數(shù)據(jù)。service中的數(shù)據(jù)。
15、MVC開發(fā)模式
jsp的發(fā)展演變歷史
1、早期只有servlet,只能使用response輸出標(biāo)簽數(shù)據(jù),非常麻煩!
2、后來有了jsp,簡化了servlet的開發(fā),如果過度應(yīng)用jsp,在jsp中際寫大量的java代碼,又寫大象的html代碼,造成難于維護(hù),難于分工協(xié)作。
3、再后來,java的web開發(fā),借鑒mvc開發(fā)魔術(shù),是得程序的設(shè)計(jì)更加的合理。-
MVC:
- M:Model,模型。完成具體的業(yè)務(wù)操作,如:查詢數(shù)據(jù)庫,封裝對象。
- V:view,視圖。展示數(shù)據(jù)。
- C:controller,控制器。:獲取用戶的輸入,調(diào)用模型,傳給視圖。
-
優(yōu)缺點(diǎn):
- 耦合性低。
- 重用性高。
- 使得小項(xiàng)目麻煩。
EL表達(dá)式
${3>4}
\${3>4} // 忽視el表達(dá)式
- 使用:
${域名稱.域名}:從指定域中獲取指定的值
1. pageScope ---------> pageContext
2. requestScope----------> request
3. sessionScope----------> session
4. applacationScope------>applation(servletContext)
16、過濾器的使用
package com.example.demoLogin;
import javax.servlet.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebFilter(filterName = "MyFilter", value = {"/*"})
public class MyFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
// 放行
chain.doFilter(request, response);
}
}