JavaWeb知識梳理

JavaWeb

靜態web資源(如html 頁面):指web頁面中供人們瀏覽的數據始終是不變。html

動態web資源:指web頁面中供人們瀏覽的數據是由程序產生的,不一樣時間點訪問web頁面看到的內容各不相同前端

靜態web資源開發技術:HTML、CSS、JavaScript。java

動態web資源開發技術:JSP/Servlet、ASP、PHP等。在Java中,動態web資源開發技術統稱爲Java Web。mysql

Web服務器

技術講解

ASP:微軟,國內最先流行的是ASP,在HTML中嵌入了VB的腳本,ASP+COM,維護成本高。web

PHP:開發速度很快,功能很強大,跨平臺,代碼簡單,可是沒法承載大訪問量的狀況(侷限性)。sql

JSP/Servlet:sun公司主推的B/S架構,基於java語言,能夠承載三高問題(高併發,高可用,高性能)。數據庫

B/S:瀏覽器和服務器;C/S:客戶端和服務器。apache

Web服務器

服務器用來處理用戶的一些請求,響應給用戶一些數據。編程

IIS:微軟的,主要用於ASP,Windows中自帶的服務器。後端

Tomcat:Tomcat是Apache 軟件基金會(Apache Software Foundation)的Jakarta 項目中的一個核心項目,最新的Servlet 和JSP 規範老是能在Tomcat 中獲得體現,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 規範。由於Tomcat 技術先進、性能穩定,並且免費,於是深受Java 愛好者的喜好並獲得了部分軟件開發商的承認,成爲目前比較流行的Web 應用服務器。

Tomcat 服務器是一個免費的開放源代碼的Web 應用服務器,屬於輕量級應用服務器,在中小型系統和併發訪問用戶不是不少的場合下被廣泛使用,是開發和調試JSP 程序的首選。對於一個JavWeb初學者來講,是最好的選擇。

Tomcat 實際上運行JSP 頁面和Servlet。

Tomcat

安裝Tomcat:官網下載(http://tomcat.apache.org/)壓縮包,解壓至指定目錄(可選:配置環境變量)。

在bin目錄下點擊startup.bat啓動,在瀏覽器網址欄輸入localhost:8080測試。

網站是如何進行訪問的:

  • 輸入用戶名,回車
  • 檢查本機的C:\Windows\System32\drivers\etc\hosts配置文件有沒有這個域名的映射
    • 有就直接返回對應的ip地址
    • 沒有就去DNS(全世界的域名管理)服務器上尋找,找到就返回

Http

Http(超文本傳輸協議):http是一個簡單的請求-響應協議,它一般運行在TCP之上。(默認端口:80)

Https:443

  • Http1.0:客戶端能夠與web服務器鏈接後,只能得到一個web資源,斷開鏈接。
  • Http1.1:客戶端能夠與web服務器鏈接後,能夠得到多個web資源。

Http請求

  • 客戶端----發請求----服務器

百度爲例:

Request URL: https://www.baidu.com/    請求地址
Request Method: GET    請求方法
Status Code: 200 OK    狀態碼
Remote Address: 180.101.49.11:443   遠程地址
Referrer Policy: no-referrer-when-downgrade

Http響應

  • 服務器----發請求----客戶端

百度響應:

Cache-Control: private    緩存控制
Connection: keep-alive    保持鏈接
Content-Encoding: gzip    編碼
Content-Type: text/html;charset=utf-8    類型

請求方式:

get:請求可以攜帶的參數比較少,大小有限制,會在瀏覽器地址欄顯示參數的內容,不安全,可是高效。

post:請求可以攜帶的參數沒有限制,大小沒有限制,不會再瀏覽器地址欄顯示參數的內容,安全,但不高效。

響應狀態碼:

200:請求響應成功

3**:請求重定向

404:找不到資源

500:服務器代碼錯誤,502:網關錯誤

Maven

Maven:項目架構管理工具,自動導入jar包(約定大於配置)。

下載Maven後解壓,配置環境變量,將bin目錄的路徑配置到path中,在cmd中輸入mvn-version,查看是否配置成功

在conf目錄下setting的 下配置本地倉庫

D:\Environments\apache-maven-3.6.3\maven-repo

在conf目錄下setting的 中配置阿里雲的鏡像

<!-- 設置阿里雲鏡像-->
<mirror>
    <id>alimaven</id>
    <mirrorOf>central</mirrorOf>
    <name>aliyun maven</name>
    <url>https://maven.aliyun.com/repository/public/</url>
</mirror>

pom.xml

pom.xml:maven的核心配置文件

因爲maven的約定大於配置,咱們以後寫的配置文件可能沒法導出或者沒法生效,就須要在maven配置下面配置resouce。

Servlet

servlet就是sun公司開發動態web的一門技術,sun公司在API中提供了一個接口叫Servlet,若是須要開發一個Servlet程序,須要編寫一個類去實現Servlet接口,再把開發好的java類部署到web服務器中。

HelloServlet

sun公司有兩個Servlet接口的默認實現類:HttpServlet和GenericServlet

  1. 構建一個maven項目,刪除裏面的src項目,之後就直接新建model,這個空的工程就是Maven的主工程。

  2. 關於Maven父子工程的理解:

父項目中會有

<modules>
    <module>servlet-01</module>
</modules>

​ 子項目中有

<parent>
        <artifactId>javaweb-02-servlet</artifactId>
        <groupId>com.zr</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
  1. Maven環境優化:修改web.xml爲最新的,將Maven的結構搭建完整。

  2. 編寫一個普通類,實現Servlet接口,繼承HttpServlet。

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter();  //響應流
        writer.println("Hello Servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  1. 編寫Servlet的映射:咱們寫的是java程序,可是要經過瀏覽器訪問,而瀏覽器要鏈接web服務器,因此咱們要在web服務器註冊咱們寫的Servlet,還須要給它一個瀏覽器可以訪問的路徑。
<!--註冊Servlet-->
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.zr.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet請求路徑-->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
  1. 配置Tomcat
  2. 啓動測試

Servlet原理

Servlet是由Web服務器調用,web服務器收到請求後,會:

Mapping

  1. 一個Servlet能夠指定一個映射路徑

    <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>/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>
  5. 一個Servlet能夠指定一些後綴或者前綴映射路徑

    <!--*前面不能加任何映射的路徑-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.zzr</url-pattern>
    </servlet-mapping>

優先級問題:

指定了固有的映射路徑,優先級最高,找不到就會走默認的處理請求。

處理404頁面

<!--404-->
<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.zr.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

ServletContext

web容器在啓動的時候,它會爲每個web程序都建立一個ServletContext對象,它表明了當前的 web應用。

  • 共享數據

    我在這個Servle中保存的數據能夠在另一個Servle中拿到

    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("hello");
            //this.getInitParameter();   初始化參數
            //this.getServletConfig();   Servlet的配置
            //this.getServletContext();   Servlet上下文
    
            ServletContext context = this.getServletContext();
            String username = "週週";
            context.setAttribute("username",username);//將一個數據保存在ServletContext中
    
        }
    }
    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.setCharacterEncoding("utf-8");
            resp.setContentType("text/html");
            resp.getWriter().println("名字:"+username);
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        }
    }
    <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.zr.servlet.HelloServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    
    <servlet>
        <servlet-name>get</servlet-name>
        <servlet-class>com.zr.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>get</servlet-name>
        <url-pattern>/get</url-pattern>
    </servlet-mapping>

    測試訪問結果

  • 獲取初始化參數

    <!--配置一個web應用的初始化參數-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybaits</param-value>
    </context-param>
    
    <servlet>
            <servlet-name>gp</servlet-name>
            <servlet-class>com.zr.servlet.ServletDemo03</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>gp</servlet-name>
            <url-pattern>/gp</url-pattern>
        </servlet-mapping>
    public class ServletDemo03 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            String url = context.getInitParameter("url");
            resp.getWriter().println(url);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
  • 請求轉發

    public class ServletDemo04 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//轉發的請求路徑
            requestDispatcher.forward(req,resp);//轉發
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
    <servlet>
        <servlet-name>sd4</servlet-name>
        <servlet-class>com.zr.servlet.ServletDemo04</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sd4</servlet-name>
        <url-pattern>/sd4</url-pattern>
    </servlet-mapping>
  • 讀取資源文件

    properties

    • 在Java目錄下新建propreties(須要在pom.xml下配置resources)
    • 在resources目錄下新建properties

    發現都被打包到了target下的class目錄下,咱們稱這個路徑爲類路徑classpath。

    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 properties = new Properties();
            properties.load(is);
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            resp.getWriter().println("username:"+username);
            resp.getWriter().println("password:"+password);
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    <servlet>
        <servlet-name>sd5</servlet-name>
        <servlet-class>com.zr.servlet.ServletDemo05</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sd5</servlet-name>
        <url-pattern>/sd5</url-pattern>
    </servlet-mapping>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <excludes>
                    <exclude>**/*.properties</exclude>
                    <exclude>**/*.xml</exclude>
                </excludes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
    //文件 db.properties
    username=root
    password=123456

HttpServletResponse

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_OK = 200;
...
int SC_MULTIPLE_CHOICES = 300;
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_INTERNAL_SERVER_ERROR = 500;
int SC_BAD_GATEWAY = 502;

下載文件

  1. 向瀏覽器輸出消息

  2. 下載文件

    1. 獲取下載文件的路徑
    2. 下載的文件名
    3. 讓瀏覽器支持下載咱們須要的東西
    4. 獲取下載文件的輸入流
    5. 建立緩衝區
    6. 得到OutputStream對象
    7. 將FileOutputStream流寫入到buffer緩衝區
    8. 將OutputStream緩衝區中的對象輸出到客戶端
    public class FileServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1. 獲取下載文件的路徑
            String realPath = "D:\\IDEACode\\javaweb-02-servlet\\response\\src\\main\\resources\\1.PNG";
            System.out.println("下載文件的路徑:"+realPath);
            //2. 下載的文件名
            String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
            //3. 讓瀏覽器支持下載咱們須要的東西
            resp.setHeader("Content-Disposition","attachment;filename="+fileName);
            //4. 獲取下載文件的輸入流
            FileInputStream in = new FileInputStream(realPath);
            //5. 建立緩衝區
            int len = 0;
            byte[] buffer = new byte[1024];
            //6. 得到OutputStream對象
            ServletOutputStream out = resp.getOutputStream();
            //7. 將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 {
            doGet(req, resp);
        }
    }

驗證碼功能

如何生成驗證碼:

  • 前端
  • 後端:須要用Java的圖片類,生成一個圖片
public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //讓瀏覽器5秒刷新一次
        resp.setHeader("refresh","5");
        //建立圖片
        BufferedImage image = new BufferedImage(300,60,BufferedImage.TYPE_INT_RGB);
        //獲得圖片
        Graphics g = image.getGraphics(); //筆
        //設置圖片的背景顏色
        g.setColor(Color.green);
        g.fillRect(0,0,300,60);
        //給圖片寫數據
        g.setColor(Color.magenta);
        g.setFont(new Font(null,Font.BOLD,70));
        g.drawString(makeNum(),0,60);
        //瀏覽器以圖片的形式打開
        resp.setContentType("image/png");
        //網站存在緩存。不讓瀏覽器緩存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");

        //把圖片顯示出來
        boolean write = ImageIO.write(image,"jpg",resp.getOutputStream());

    }
    //生成隨機數
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        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 {
        doGet(req, resp);
    }
}
<!--註冊Servlet-->
<servlet>
    <servlet-name>image</servlet-name>
    <servlet-class>com.zr.servlet.ImageServlet</servlet-class>
</servlet>
<!--Servlet請求路徑-->
<servlet-mapping>
    <servlet-name>image</servlet-name>
    <url-pattern>/image</url-pattern>
</servlet-mapping>

實現重定向

void sendRedirect(String var1) throws IOException;//重定向
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       /*
       resp.setHeader("Location","/r/image");
       resp.setStatus(302);
        */
       
        resp.sendRedirect("/r/image");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

配置web.xml測試

重定向和轉發的區別:

相同點:頁面都會發生跳轉

不一樣點:

  • 請求轉發的時候,url不會改變 307
  • 重定向的時候,url地址欄會發生變化 302

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<%--提交的路徑須要尋找到當前項目的路徑--%>
<form action="${pageContext.request.contextPath}/login" method="post">
    用戶名:<input type="text" name="username"><br>
    密碼 :<input type="password" name="password"><br>
    <input type="submit">

</form>
</body>
</html>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>
public class RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("進入這個請求了");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("username:"+username);
        System.out.println("password:"+password);
        resp.sendRedirect("/r/success.jsp");
        
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<!--註冊Servlet-->
<servlet>
    <servlet-name>test</servlet-name>
    <servlet-class>com.zr.servlet.RequestTest</servlet-class>
</servlet>
<!--Servlet請求路徑-->
<servlet-mapping>
    <servlet-name>test</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

HttpServletRequest

HttpServletRequest表明客戶端的請求,用戶經過http協議訪問服務器,http請求中的全部的信息會被封裝到HttpServletRequest,經過這個HttpServletRequest的方法,得到客戶端的全部信息。

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");

        System.out.println("==================================");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));

        //請求轉發
        //這裏的/表明當前的web應用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);

    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陸</title>
</head>
<body>
<h1>登陸</h1>
<div style="text-align: center">
    <form action="${pageContext.request.contextPath}/login" method="post">
        用戶名:<input type="text" name="username"><br>
        密碼:<input type="password" name="password"><br>
        愛好:
        <input type="checkbox" name="hobbys" value="唱歌">唱歌
        <input type="checkbox" name="hobbys" value="女孩">女孩
        <input type="checkbox" name="hobbys" value="寫字">寫字
        <input type="checkbox" name="hobbys" value="代碼">代碼
        <br>
        <input type="submit">
    </form>

</div>
</body>
</html>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>登陸成功</h1>
</body>
</html>

web.xml

<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.zr.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

cookie

  • 客戶端技術(響應,請求)

session

  • 服務器技術,能夠保存用戶的會話信息,咱們能夠把信息或數據放在session中

常見應用:網站登陸一次後,下次能夠直接進入。

從請求中拿到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");
        resp.setContentType("text/html;charset=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()+"");
        //有效期爲1天
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml

<servlet>
    <servlet-name>CookieDemo01</servlet-name>
    <servlet-class>com.zr.servlet.CookieDemo01</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>CookieDemo01</servlet-name>
    <url-pattern>/c1</url-pattern>
</servlet-mapping>

cookie:通常會保存在本地的用戶目錄下appdata;

  • 一個cookie只能保存一個信息
  • 一個web站點能夠給瀏覽器發送多個cookie,最多存放20個cookie
  • cookie的大小有限制4kb
  • cookie瀏覽器上限300個

刪除cookie

  • 不設置有效期,關閉瀏覽器,自動失效
  • 設置有效期時間爲0

Session

session:

  • 服務器會給每個用戶(瀏覽器)建立一個session對象

  • 一個session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個session就存在

  • 用戶登陸以後,整個網站均可以訪問,-->保存用戶的信息

session和cookie的區別:

  • cookie是把用戶的數據寫給用戶的瀏覽器,瀏覽器保存(能夠保存多個)
  • session是把數據寫到用戶獨佔的session中,服務器保存(保存重要的信息,減小資源的浪費)
  • session對象由服務器建立

session保存數據

package com.zr.pojo;

public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
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",new Person("週週",1));
        //得到session的id
        String id = session.getId();
        //判斷session是否是新建立的
        if(session.isNew()){
            resp.getWriter().write("session建立成功,ID:"+ id);
        }else {
            resp.getWriter().write("session已經存在,ID:"+ id);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
public class SessionDemo02 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();

        Person person = (Person) session.getAttribute("name");
        System.out.println(person);

    }

    @Overridejava
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<servlet>
    <servlet-name>SessionDemo01</servlet-name>
    <servlet-class>com.zr.servlet.SessionDemo01</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>SessionDemo01</servlet-name>
    <url-pattern>/s1</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>SessionDemo02</servlet-name>
    <servlet-class>com.zr.servlet.SessionDemo02</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>SessionDemo02</servlet-name>
    <url-pattern>/s2</url-pattern>
</servlet-mapping>

session手動註銷

public class SessionDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        //手動註銷session
        session.invalidate();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

session自動註銷

<!--設置session註銷時間-->
<session-config>
    <!--1分鐘後自動失效-->
    <session-timeout>1</session-timeout>
</session-config>

JSP

什麼是JSP

jsp:java server pages,Java服務器端界面,和servlet同樣,用於開發動態web技術。

特色

  • 寫jsp就像寫html
  • 區別
    • html只給用戶提供靜態的數據
    • jsp頁面能夠嵌入Java代碼,爲用戶提供動態數據

jsp原理

在服務器內部,tomcat中有一個work目錄,jsp最終被轉化成了Java類, jsp本質就是一個servlet。

index_jsp.java源碼

//初始化
 public void _jspInit() {
  }
//銷燬
  public void _jspDestroy() {
  }
//jspService
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)

判斷請求

內置的一些對象

final javax.servlet.jsp.PageContext pageContext; //頁面上下文
    javax.servlet.http.HttpSession session = null;  //session
    final javax.servlet.ServletContext application;  //applicationContext
    final javax.servlet.ServletConfig config;  //config
    javax.servlet.jsp.JspWriter out = null;  //out
    final java.lang.Object page = this;  //page 當前頁
	HttpServletRequest request  //請求
    HttpServletResponse respons  //響應

輸出頁面前增長的代碼

response.setContentType("text/html"); //設置響應的頁面類型
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

以上的對象能夠在jsp中直接使用

在jsp頁面中,java代碼會原封不動的輸出,若是是html代碼就會被轉化爲out.write(".....");

JSP基礎語法

任何語言都有本身的語法 ,jsp做爲Java技術的一種運用,它擁有一些本身擴充的語法(瞭解)。Java語法它都支持。

jsp表達式

<%--JSP表達式 輸出時間到客戶端--%>
<%= new java.util.Date()%>

jsp腳本片斷

<%--jsp腳本片斷--%>
<%
  int sum=0;
  for (int i = 0; i < 100; i++) {
    sum+=i;
  }
  out.println("<h1>sum="+sum+"</h1>");
%>

腳本片斷的再實現

<%
  int x=10;
  out.print(x);
%>
<p>這是一個jsp文檔</p>
<%
  int y=20;
  out.print(y);
%>


<%--在代碼中嵌入html元素--%>
<%
  for (int i = 0; i < 5; i++) {
%>
  <h1>helloworld<%=i%></h1>
<%
  }
%>

jsp聲明

<%!
  static {
    System.out.println("loding...");
  }
  private int globalvar=0;
  public void jspInit(){
    System.out.println("進入了方法");
  }
%>

JSP聲明:會被編譯到jsp生成的Java類中。其它的會被生成到jspServer方法中。

JSP的註釋不會在客戶端源碼顯示,HTML的註釋會在哭護短源碼顯示。

定製錯誤頁面

<error-page>
    <error-code>404</error-code>
    <location>/error/404.jsp</location>
</error-page>

<error-page>
    <error-code>500</error-code>
    <location>/error/500.jsp</location>
</error-page>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>Title</title>
</head>
<body>
<img src="img/500.jpg" alt="500">
</body>
</html>

JSP指令

<%@page% args...>
<%@include file=""%>


<%--會將頁面合二爲一--%>
<%@include file="common/header.jsp"%>
<h1>主體</h1>
<%@include file="common/footer.jsp"%>

<hr>
<%--jsp標籤  拼接頁面--%>
<jsp:include page="common/header.jsp"/>
<h1>主體</h1>
<jsp:include page="common/footer.jsp"/>

九大內置對象

  • PageContext 存東西
  • Request 存東西
  • Response
  • Session 存東西
  • Application 【ServletContext】存東西
  • config 【ServletConfig】
  • out
  • page
  • exception

四大做用域

<%--內置對象--%>
<%
    pageContext.setAttribute("name1","周1");//保存的數據只在一個頁面內有效
    request.setAttribute("name2","周2");//保存的數據只在一次請求中有效,請求轉發會攜帶
    session.setAttribute("name3","周3");//保存的數據只在一次會話中有效,打開瀏覽器到關閉瀏覽器
    application.setAttribute("name4","周4");//保存的數據在服務器中有效,打開服務器到關閉服務器   
%>
<%--經過pageContext取值--%>
<%
    //經過尋找的方式
    String name1 = (String) pageContext.findAttribute("name1");
    String name2 = (String) pageContext.findAttribute("name2");
    String name3 = (String) pageContext.findAttribute("name3");
    String name4 = (String) pageContext.findAttribute("name4");
    String name5 = (String) pageContext.findAttribute("name5");//不存在
%>

<%--使用EL表達式輸出  ${}--%>
<h1>取出的值爲:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>

    <hr>
<%=name5%>

request:客戶端向服務器發送數據,產生的數據,用戶看完就沒用了,好比:新聞

session:客戶端向服務器發送數據,產生的數據,用戶用完一會還會用,好比:購物車

application:客戶端向服務器發送數據,產生的數據,一個用戶使用完了,其它用戶可能還用,好比:聊天記錄

JSP標籤,JSTL標籤,EL表達式

<!-- jstl表達式的依賴 -->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- standard標籤庫 -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

EL表達式:${}

  • 獲取數據
  • 執行運算
  • 獲取web開發的經常使用對象

JSP標籤:

<%--jsp:include--%>

<%--轉發時候攜帶參數--%>
<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="zr"/>
    <jsp:param name="age" value="22"/>

</jsp:forward>

JSTL表達式

JSTL標籤庫的使用就是爲了彌補HTML標籤的不足;它自定義了許多的標籤,能夠供咱們使用,標籤的功能和Java代碼同樣。

核心標籤(掌握),格式化標籤,SQL標籤,XML標籤

<%--引入JSTL核心標籤庫--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

JSTL標籤使用步驟

  • 引入對應的taglib
  • 使用其中的方法
  • tomcat中須要引入JSTL的包,不然會報JSTL解析錯誤

c:if

<body>
<h1>if測試</h1>
<hr>
<form action="coreif.jsp" method="get">
    <%-- EL表達式獲取表單中的數據
        ${param.參數名}
    --%>
    <input type="text" name="username" value="${param.username}"/>
    <input type="submit" name="登陸">

</form>

<%--    判斷若是提交的用戶是管理員,則登陸成功--%>
<c:if test="${param.username=='admin'}" var="isadmin">
    <c:out value="管理員歡迎你!"/>
</c:if>
<c:out value="${isadmin}"/>
</body>

c:choose

<body>
<%--定義一個變量score 值爲88--%>
<c:set var="score" value="88"/>
<c:choose>
    <c:when test="${score>=90}">
        你的成績優秀!
    </c:when>
    <c:when test="${score>=80}">
        你的成績良好!
    </c:when>
    <c:when test="${score>=60}">
        你的成績通常!
    </c:when>
    <c:when test="${score<=60}">
        你的成績不合格!
    </c:when>
</c:choose>
</body>

c:forEach

<body>
<%
    ArrayList<String> people = new ArrayList<String>();
    people.add(0,"張三");
    people.add(1,"李四");
    people.add(2,"王五");
    people.add(3,"趙六");
    people.add(4,"田七");
    request.setAttribute("list",people);
%>
<%-- var 每一次遍歷的變量  items每次遍歷的對象--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"/><br>
</c:forEach>
<hr>
<%--開始 結束 步長--%>
<c:forEach var="people" items="${list}" begin="2" end="4" step="2">
    <c:out value="${people}"/><br>
</c:forEach>

</body>

JavaBean

實體類

JavaBean有特定的寫法:

  • 必需要有一個無參構造
  • 屬性必須私有化
  • 必須有對應的get/set方法

通常用來和數據庫的字段作映射 ORM;

ORM對象關係映射

  • 表--->類
  • 字段--->屬性
  • 行記錄--->對象

people表

id name age address
1 周1 18 武漢
2 周2 22 廣州
3 周3 100 佛山

創建數據庫相應的字段後建立java實體類

package com.zr.pojo;
//實體類 通常是和數據庫中的表結構一一對應的
public class People {
    private int id;
    private String name;
    private int age;
    private String address;

    public People() {
    }

    public People(int id, String name, int age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "People{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}
<%@ page import="com.zr.pojo.People" %><%--
  Created by IntelliJ IDEA.
  User: zr
  Date: 2020/10/11
  Time: 22:08
  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>
<%
//    People people = new People();
//    people.setAddress();
//    people.setId();
//    people.setAge();
//    people.setName();
 //和下面的等價
%>
<jsp:useBean id="people" class="com.zr.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="武漢"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="18"/>
<jsp:setProperty name="people" property="name" value="小周"/>

姓名:<jsp:getProperty name="people" property="name"/>
id:<jsp:getProperty name="people" property="id"/>
年齡:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>
</body>
</html>

MVC三層架構

MVC:model,view,controller 模型視圖控制器

Model

  • 業務處理,業務邏輯(Service)
  • 數據持久層,CRUD(Dao)

View

  • 展現數據
  • 提供操做發起Servlet請求(a,form,img ....)

Controller(Servlet)

  • 接收請求,(req:請求參數,session信息...)
  • 交給業務層處理相應的代碼
  • 控制視圖的跳轉
登陸--->接收用戶的登陸請求--->處理用戶的請求(得到用戶登陸的參數 username password)--->交給業務層處理登陸的業務(判斷用戶名密碼是否正確)--->Dao層查詢用戶密碼是否正確--->數據庫

過濾器

Filter:過濾器,用來過濾網站的數據:

  • 處理中文亂碼
  • 登陸驗證...

Filter編寫:先配置Servlet,jsp依賴

實現Filter(Servlet下的)接口,重寫對應的方法

public class CharacterEncodingFilter implements Filter {
    //初始化   web服務器啓動就初始化了,隨時等待監聽對象出現
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter初始化");
    }
    //Chain :鏈
    /*
    1,過濾器中的全部代碼,在過濾特定請求時都會執行
    2,必需要讓過濾器過濾同行
    chain.doFilter(request,response);
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;character=UTF-8");

        System.out.println("CharacterEncodingFilter執行前....");
        chain.doFilter(request,response);//讓咱們的請求繼續走 若是不寫,程序被攔截中止
        System.out.println("CharacterEncodingFilter執行後....");

    }
    //銷燬   web服務器關閉的時候,過濾器銷燬
    public void destroy() {
        System.out.println("CharacterEncodingFilter銷燬");

    }
}

servlet顯示亂碼

public class ShowServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //resp.setCharacterEncoding("utf-8");
        //resp.setContentType("text/html");
        resp.getWriter().write("你好世界");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

配置web.xml

<servlet>
    <servlet-name>showServlet</servlet-name>
    <servlet-class>com.zr.servlet.ShowServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>showServlet</servlet-name>
    <url-pattern>/servlet/show</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>showServlet</servlet-name>
    <url-pattern>/show</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>CharacterEncoding</filter-name>
    <filter-class>com.zr.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncoding</filter-name>
    <!--只要是/servlet的任何請求,都會通過這個過濾器-->
    <url-pattern>/servlet/*</url-pattern>
</filter-mapping>

監聽器

統計網站在線人數:

實現一個監聽器的接口

//統計網站在線人數,統計Session
public class OnlineCountListener implements HttpSessionListener {
    //建立Session監聽
    //一旦建立一個Session就會觸發一次這個事件
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        System.out.println(se.getSession().getId());
        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
        if (onlineCount==null){
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);
    }
    //銷燬Session監聽
    //一旦銷燬一個Session就會觸發一次這個事件
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
        if (onlineCount==null){
            onlineCount = new Integer(0);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count-1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);
    }
}
/*
    Session銷燬
    1.手動銷燬  se.getSession().invalidate();
    2.自動銷燬  xml中配置<session-config>
 */

顯示在線人數

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
<h1>當前有<span style="color: hotpink"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人在線</h1>
  </body>
</html>

配置web.xml

<!--註冊監聽器-->
    <listener>
        <listener-class>com.zr.listener.OnlineCountListener</listener-class>
    </listener>

過濾器,監聽器常見應用

監聽器GUI編程中常用

GUI應用

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("中秋快樂!"); //新建一個窗體
        Panel panel = new Panel(null); //面板
        frame.setLayout(null); //設置窗體的佈局
        frame.setBounds(300,300,500,500); //座標
        frame.setBackground(new Color(0,0,255)); //背景顏色

        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(0,255,255));

        frame.add(panel);
        frame.setVisible(true);

        //監聽事件,監聽關閉事件
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

用戶登陸後才能進入主頁,註銷後不能進入主頁

1.用戶登陸以後向session中放入用戶的數據

2.進入主頁的時候判斷用戶是否登陸,要求在過濾器中實現login.jsp

login.jsp(web包下)

<body>
<h1>登陸</h1>
<form action=" /servlet/login" method="post">
    <input type="text" name="username">
    <input type="submit">
</form>
</body>

success.jsp(web/sys包下)

<body>
<h1>主頁</h1>
<a href="/servlet/loginout">註銷</a>
</body>

error.jsp(web包下)

<body>
<h1>錯誤</h1>
<h3>用戶名錯誤</h3>
<a href="/login.jsp">返回登陸頁面</a>
</body>

Login

public class login extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //獲取前端請求的參數
        String username = req.getParameter("username");
        if (username.equals("admin")){
            req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
            resp.sendRedirect("/sys/success.jsp");
        }else {
            resp.sendRedirect("/error.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

LoginOut

public class LoginOut extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object user_session = req.getSession().getAttribute("USER_SESSION");
        if (user_session!=null){
            req.getSession().removeAttribute("USER_SESSION");
            resp.sendRedirect("/login.jsp");
        }else {
            resp.sendRedirect("/login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

SysFilter:過濾器

public class SysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        filterChain.doFilter(request, response);

        if (req.getSession().getAttribute("USER_SESSION")==null){
            resp.sendRedirect("/error.jsp");
        }
    }

    public void destroy() {
        
    }
}

web.xml

<servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.zr.servlet.login</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/servlet/login</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>loginOut</servlet-name>
        <servlet-class>com.zr.servlet.LoginOut</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>loginOut</servlet-name>
        <url-pattern>/servlet/loginout</url-pattern>
    </servlet-mapping>


    <filter>
        <filter-name>CharacterEncoding</filter-name>
        <filter-class>com.zr.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncoding</filter-name>
        <!--只要是/servlet的任何請求,都會通過這個過濾器-->
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.zr.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <!--只要是/sys的任何請求,都會通過這個過濾器-->
        <url-pattern>/sys/*</url-pattern>
    </filter-mapping>

JDBC

Java鏈接數據庫,導入JDBC依賴mysql-connector-java,IDEA中鏈接數據庫

public class TestJdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //配置信息
        String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "123456";
        //加載驅動
        Class.forName("com.mysql.jdbc.Driver");
        //鏈接數據庫
        Connection connection = DriverManager.getConnection(url, username, password);
        //向數據庫發送sql的對象
        Statement statement = connection.createStatement();
        //編寫sql
        String sql = "select * from users";
        //執行查詢sql,返回一個結果集
        ResultSet rs = statement.executeQuery(sql);

        while (rs.next()){
            System.out.println("id="+rs.getObject("id"));
            System.out.println("name="+rs.getObject("name"));
            System.out.println("password="+rs.getObject("password"));
            System.out.println("email="+rs.getObject("email"));
            System.out.println("birthday="+rs.getObject("birthday"));
        }
        //關閉鏈接
        rs.close();
        statement.close();
        connection.commit();
    }
}

預編譯sql

public class TestJdbc2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //配置信息
        String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "123456";
        //加載驅動
        Class.forName("com.mysql.jdbc.Driver");
        //鏈接數據庫
        Connection connection = DriverManager.getConnection(url, username, password);
        //向數據庫發送sql的對象
        Statement statement = connection.createStatement();

        String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1,4);
        preparedStatement.setString(2,"周七");
        preparedStatement.setString(3,"888888");
        preparedStatement.setString(4,"666@qwq.com");
        preparedStatement.setString(5, String.valueOf(new Date(new java.util.Date().getTime())));
        int i = preparedStatement.executeUpdate();
        if (i>0){
            System.out.println("插入成功");
        }
        //關閉鏈接

        statement.close();
        connection.commit();
    }
}

事務

要麼都成功,要麼都失敗 !

ACID原則,保證數據的安全。

開啓事務

事務提交 commi ()

事務回滾 rollback ()

關閉事務

Junit單元測試

依賴

<!--單元測試-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

簡單使用

@Test註解只在方法上有效,只要加了這個註解的方法,就能夠直接運行。

public class TestJdbc3 {

    @Test
    public void test(){
        System.out.println("Hello");
    }
}

轉帳事務(建立account表,字段id,name,money),使用單元測試

public class TestJdbc3 {

    @Test
    public void test() {
        //配置信息
        String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "123456";
        Connection connection=null;
        //加載驅動
        try {
            Class.forName("com.mysql.jdbc.Driver");
        //鏈接數據庫
        connection = DriverManager.getConnection(url, username, password);
        //通知數據庫開啓事務
        connection.setAutoCommit(false);
        String sql1 = "update account set money=money-100 where name='A'";
        connection.prepareStatement(sql1).executeUpdate();

        //製造錯誤
        int i=1/0;

        String sql2 = "update account set money=money+100 where name='B'";
        connection.prepareStatement(sql2).executeUpdate();

        connection.commit();//以上sql都執行成功才提交
        System.out.println("提交成功!");
        } catch (Exception e) {
            try {
                //若是出現異常,就回滾事務
                connection.rollback();
                System.out.println("轉帳失敗!");
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}
相關文章
相關標籤/搜索