[crazy God Theory] JavaWeb notes (middle)

Keywords: JDBC JSP Session cookie filter

JavaWeb (medium)

Cookie s and sessions

1. Conversation

Session: users open a browser, click many hyperlinks, access multiple web resources, and close the browser. This process can be called session;

Stateful conversation: when a classmate comes to the classroom next time, we will know that the classmate has been here, which is called stateful conversation;

A website, how to prove you've been here?

  1. The server sends a letter to the client, and the client can bring the letter to the server next time; cookie
  2. The server registers that you have been here. Next time you come, I will match you; session

2. Two techniques for saving sessions

cookie

  • Client Technology (response, request)

session

  • Server technology, which can save the user's Session information? We can put information or data in the Session!

Common example: after you log in to the website, you don't need to log in again next time. You can go up directly for the second visit!

[do you really know cookies and sessions? - pure smile - blog Garden (cnblogs. Com)]( https://www.cnblogs.com/ityouknow/p/10856177.html#: ~: text = what is the difference between a Cookie and a Session?. the scope of action is different. Cookies are saved in the client (browser) , the Session is saved on the server side. Depending on the access method, the Cookie keeps some common variable information, such as UserId, etc. the validity period is different, and the Cookie can be set to keep for a long time. For example, the default login function we often use, the Session generally has a short expiration time, and the client will fail when the client is closed or the Session times out.)

Cookie

package com.szg.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // i'll tell you the time you came, and then encapsulate the time into a token. Next time you bring this token, i'll know you've been here

        //Preliminary code for solving Chinese garbled code
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //According to the further code provided by the barrage
        resp.setContentType("text/html");

        PrintWriter out = resp.getWriter();
        //Server charging client acquisition
        Cookie[] cookies = req.getCookies();

        //Determine whether the cookie exists
        //The crazy God wrote here is wrong, because there must be cookie s, and the browser itself will generate several browsers, so there must be no "this is your first visit to this site" 
        //It is possible to solve this problem by setting it to detect the existence of key value pairs
        if(cookies!=null){
            out.write("Your last visit was:");
            for(int i=0;i<cookies.length;i++){
                Cookie cookie = cookies[i];
                if(cookie.getName().equals("lastLoginTime")){
                    //Gets the value of cokie and the forced conversion type
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date =new Date(lastLoginTime);
                    //Expired functions are not recommended
                    out.write(date.toLocaleString());
                }
            }
        }
        else{
            out.write("This is your first visit to this site");
        }
        //The service converts a cookie to a string type to the client
        // It must be converted to string type. You can add an empty string after it, or an error will be reported
        Cookie cookie =new Cookie("lastLoginTime",System.currentTimeMillis()+"");
        resp.addCookie(cookie);

    }

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

Where the edge browser can also view cookie s: (ignore a wrong word)

The response cookie is the value of the next request cookie

Then I found that every time I shut down the browser, my last lastLoginTime will be cleared, so I can set a validity period to ensure that the cookie is valid on this day.

. . . 
cookie.setMaxAge(24*60*60);// Set a one-day validity period
resp.addCookie(cookie);//Add cookie
. . . 
  1. Get cookie information from the request
  2. The server responds to the client cookie

Common functions

Cookie[] cookies = req.getCookies(); //Get cookies
cookie.getName(); //Get the key in the cookie
cookie.getValue(); //Get vlaue in cookie
new Cookie("lastLoginTime", System.currentTimeMillis()+""); //Create a new cookie
cookie.setMaxAge(24*60*60); //Set the validity period of the cookie
resp.addCookie(cookie); //Respond to a cookie to the client

Cookies are generally saved in the appdata folder under the local user directory;

Is there an upper limit for a website cookie?

  • A Cookie can only save one information;
  • A web site can send multiple cookies to the browser and store up to 20 cookies;
  • The Cookie size is limited to 4kb;
  • 300 cookie browser limit

Method of deleting cookies

  • If the validity period is not set, close the browser and it will automatically become invalid;
  • Set the validity time to 0;

One more idea when encountering Chinese garbled Code:

// It takes time to encode before decoding
URLEncoder.encode("Qin Jiang","utf-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")

Session (key)

What is a Session:

  • The server will create a Session object for each user (browser);
  • A Session monopolizes a browser. As long as the browser is not closed, the Session exists;
  • After the user logs in, the whole website can be accessed! – > save the user's information; save the shopping cart information

SessionDemo01

package com.szg.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

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

        //Solve the problem of garbled code
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        //Get Session
        HttpSession session = req.getSession();
        //Save something in the Session
        //The second value type is Object, that is, all types can be used, not limited to string entity objects
        session.setAttribute("name","SZG");
        //Gets the ID of the Session
        String sessionId = session.getId();

        //Judge whether the Session is newly created

        //Generally, when you open the browser, you will jump to localhost:8080 / when you create a session and then enter demo1, so you will be prompted that it has been created
        //Therefore, if you change the url to localhost:8080/s1 in tomcat, you will be prompted that the creation is successful by opening the browser and directly entering demo1

        if (session.isNew()){
            resp.getWriter().write("session Created successfully,ID:"+sessionId);
        }else {
            resp.getWriter().write("session And exists in the server,ID:"+sessionId);
        }

        //What was done when the Session was created;
        // It's equivalent to building a cookie
//        Cookie cookie = new Cookie("JSESSIONID",sessionId);
//        resp.addCookie(cookie);

    }

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

SessionDemo02

package com.szg.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

//Run demo1 to output SZG first
//Run demo2 first and output null
//session and servletcontext are somewhat similar. They can be used to share data and play the role of "cloud"
//Different browsers have different session s
public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //Solve the problem of garbled code
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        //Get the Session and output the id
        HttpSession session = req.getSession();
        String id = (String) session.getAttribute("name");
        System.out.println(id);
    }

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

SessionDemo03

package com.szg.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
//Manually log off the session. At that time, a new session will be generated immediately, so the session must exist
//Run demo3 first, and "session created successfully" will appear when running demo1
public class SessionDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        session.invalidate();
    }

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

Automatic logoff is configured in web.xml

<!--set up Session Default expiration time-->
<session-config>
    <!--15 Minutes later Session Automatic failure, in minutes-->
    <session-timeout>15</session-timeout>
</session-config>

The difference between Session and cookie: (combined with the previous link)

  • Cookie is to write the user's data to the user's browser, and the browser saves it (multiple can be saved)
  • Session writes the user's data to the user's exclusive session and saves it on the server (saves important information and reduces the waste of server resources)
  • The Session object is created by the service;

Session usage scenario:

  • Save the information of a login user;
  • Shopping cart information;
  • We save the data often used in the whole website in Session;

JSP

principle

Java Server Pages: Java server-side pages, like servlets, are used for dynamic Web technology! The language running on the server side.

Biggest features:

  • Writing JSP is like writing HTML
  • difference:
    • HTML only provides users with static data
    • JAVA code can be embedded in JSP pages to provide users with dynamic data;

How does JSP execute?

  • There is no problem at the code level, just jsp files

  • Server internal work

    There is a work directory in tomcat. The server stores the directory and stores many websites. There are xxx_jsp.java files in it;

    If Tomcat is used in the IDEA, a work directory will be produced in Tomcat of the IDEA, which has the same function as the above

It is found that the pages have been converted into java files, so:

  • The browser sends a request to the server. No matter what resources it accesses, it is actually accessing the Servlet!

  • JSP will eventually be converted into a Java class!

By looking at the xxx_jsp.java code, JSP is essentially a Servlet

//initialization
public void _jspInit() {}
//Destroy
public void _jspDestroy(){} 
//JSPService has the source code to judge the submission type, such as get and post
public void _jspService(HttpServletRequest request,HttpServletResponse response){}
// Some internal objects were found
final javax.servlet.jsp.PageContext pageContext;  //Page context
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: current
HttpServletRequest request                        //request
HttpServletResponse response                      //response
//The code added before outputting the page is the content in try, followed by the output of html statements in java language
//Using the specific format of syntax in jsp, you can also use the above objects to write java statements 
response.setContentType("text/html");       //Set the page type of response to be recognized
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(); //The output object is followed by the output statement
_jspx_out = out;

flow chart:

In JSP page;

  • As long as it is JAVA code, it will be output intact;

  • If it is HTML code, it will be converted to: out.write("\r\n"); Output to front end

W3chool:

  • Just like other ordinary web pages, your browser sends an HTTP request to the server.
  • The Web server recognizes that this is a request for a jsp page and passes the request to the jsp engine. This is done by using a URL or. jsp file.
  • The JSP engine loads JSP files from disk and converts them into servlet s. This transformation simply converts all template text to println() statements and converts all JSP elements into Java code.
  • The JSP engine compiles the servlet into an executable class and passes the original request to the servlet engine.
  • A component of the Web server will call the servlet engine and then load and execute the servlet class. During execution, the servlet generates output in HTML format, embeds it in the HTTP response, and submits it to the Web server.
  • The Web server returns the HTTP response to your browser in the form of a static HTML page.
  • Finally, the Web browser processes HTML pages generated dynamically in the HTTP response as if it were static pages.

Generally, the JSP engine will check whether the servlet corresponding to the JSP file already exists and whether the modification date of the JSP file is earlier than the servlet. If the modification date of the JSP file is earlier than the corresponding servlet, the container can determine that the JSP file has not been modified and the servlet is valid. This makes the whole process more efficient and faster than other scripting languages (such as PHP).

In general, JSP Web page is to write servlet in another way without becoming a master of Java programming. In addition to the interpretation stage, JSP Web pages can be treated almost as an ordinary servlet.

Basic syntax of JSP

As an application of Java technology, JSP has its own extended syntax (understand, know!). All Java syntax supports!

You need to create a new project. This time, instead of using the javaweb template, you directly create a blank Maven project. Then right-click the project and select Add framefork Support to add a web application

This creation method is more advanced. We don't need to optimize the structure and change the web.xml file.

Of course, we also need to import dependencies in pom.xml. This time, there are a lot of imported dependencies. Wait patiently for more refreshes

<dependencies>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
    <dependency>
        <groupId>javax.servlet.jsp.jstl</groupId>
        <artifactId>jstl-api</artifactId>
        <version>1.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
    <dependency>
        <groupId>org.apache.taglibs</groupId>
        <artifactId>taglibs-standard-impl</artifactId>
        <version>1.2.5</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

JSP expression
Function: used to output the program to the client
Format: <% = variable or expression% >

Insert the following statement in index.jsp to output the time

<%-- This is a comment --%>
<%= new java.util.Date()%>
<%-- You can import at the beginning of the page java package--%>
<%@ page import="java.util.*" %>

Because there is no java file, there is no need to write servlet mapping, then configure tomcat and run the result

When the code is changed and you want to run again, [the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-s1TWx3Dg-1632541399138)(JavaWeb (2). assets/image-20210921114059684.png)]

Click rerun and select the second one to change the page without restarting (this creation method is unique to the old creation method. You need to open the browser yourself

Jsp script fragment

<%
int sum = 0;
for (int i = 1; i <=100 ; i++) {
    sum+=i;
}
out.println("<h1>Sum="+sum+"</h1>");
int x = 10;
out.println(x);
%>

<%-- Embedding in code HTML Element output five times helloword It's messy, isn't it --%>

<%  for (int i = 0; i < 5; i++) { %>
<h1>Hello,World  <%=i%> </h1>
<% } %>

Jsp declaration

<%!//JSP declaration statement is used to declare one or more variables and methods for later Java code.
    static {
    System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void kuang(){
    System.out.println("Entered the method Kuang!");
}
%>

JSP declaration: it will be compiled into the Java class generated by JSP! And JSP script and JSP expression will be generated into _jspservicemethod!

In JSP, embed Java code!

JSP comments will not be displayed on the client, and HTML will!

instructions

<%@ page ...%>

Example: Custom 500 error page

Create a new jsp file, create a folder error, and then create a 500.jsp in the folder to define the page

Of course, custom pages can be made with text and pictures as needed

JSP 2.jsp code

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- If there is an error, jump to the customized 500 page --%>
<%-- It must be ensured that idea If you open the page with 500 errors, you can jump to the customized 500 page--%>
<%@ page errorPage="error/500.jsp"%>

<html>
<head>
    <title>Title</title>
</head>
<body>
<% int x =1/0 %>
</body>
</html>

500.jsp code

<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%-- If tomcat If the project path is configured in, you need to add the project path or write it directly ${pageContext.request.contextPath}/ Mine came out--%>
<%--Some barrages say jpg Just change it into a bottle. Some say to remove one of the two points of the crazy God code. Some say to restart idea Just do it--%>

<img src="${pageContext.request.contextPath}/img/IMG_0627.jpg" alt="500">
<h1>Custom 500 error</h1>
</body>
</html>

There's absolutely no problem with the code you write, but it's hard not to automatically jump to the custom error page..

You can also directly configure the page to jump in case of 500 error in web.xml:

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

After adding this sentence, you can automatically jump to the custom error page, which is even more uncomfortable...

<%@include ...%>

Create a new folder common, which is generally used to store the common parts of each page of the whole website. Create two JSPS in the new folder to represent the page head and page tail respectively.

In the main page, two methods are used to insert the implementation effects of the head and tail

Look directly at the source code of JSP 3#u jsp.java

<%--@include file  The two pages will be combined into one, and the code contained in the head and tail will be extracted into the main page--%>
<%-- Note that because the code is directly inserted into the body page, an error will be reported when there are variables with the same name in the head, body and tail,--%>
<%@include file="common/header.jsp"%>
<h1>Web page subject</h1>
<%@include file="common/footer.jsp"%>

<hr>

<%--JSP label
    jsp:include: page Spliced pages are three in nature. They are just a reference. The code will not be directly inserted into the main page
    --%>
<jsp:include page="/common/header.jsp"/>
<h1>Web page subject</h1>
<jsp:include page="/common/footer.jsp"/>

Nine built-in objects of JSP

  • PageContext store
  • Request to store things
  • Response
  • Session storage
  • Application [servvetcontext] save things
  • config [SerlvetConfig]
  • out
  • page, don't understand
  • exception
pageContext.setAttribute("name1","Qinjiang 1"); //The saved data is only valid in one page
request.setAttribute("name2","Qinjiang 2"); //The saved data is only valid in one request, and the request forwarding will carry this data
session.setAttribute("name3","Qinjiang 3"); //The saved data is valid only in one session, from opening the browser to closing the browser
application.setAttribute("name4","Qinjiang 4");  //The saved data is only valid in the server, from opening the server to closing the server  

Create a new jsp: pageConetxtDemo01

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<% //!! Pay attention to the difference before each!!
    pageContext.setAttribute("name1","szg1 number"); //The saved data is only valid in one page
    request.setAttribute("name2","szg2 number"); //The saved data is only valid in one request, and the request forwarding will carry this data
    session.setAttribute("name3","szg3 number"); //The saved data is valid only in one session, from opening the browser to closing the browser
    application.setAttribute("name4","szg4 number");  //The saved data is only valid in the server, from opening the server to closing the server

%>
<%-- jsp Used in el Expression output ${}
el If the expression cannot be displayed normally, add it above<%@ page isELIgnored=false>The default for lower versions is true  -- From the barrage
--%>
<h1>The retrieved value is</h1>
<h2>${name1}</h2>
<h2>${name2}</h2>
<h2>${name3}</h2>
<h2>${name4}</h2>
<%--There is no response to the following sentence because name5 It doesn't exist!!!--%>
<h2>${name5}</h2>

<%//The search order is first the page object with the smallest range, then the request object, session object, and finally the application object. The return value of this method is the value of the first Java object that meets the requirements.
    //From the bottom to the top
    //The following shows how to get the page object in the page through key search in java code
    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"); //non-existent
%>
<%--Page direct output null --%>
<h2><%=name5%>></h2>

</body>
</html>

You can get the outermost information in the application in the video. In the video, crazy God gives examples of three clients taking things from the server-side library and counting the number of online people.

In fact, servletContext and application are the same, which is equivalent to a class creating two variables with different names
In the servlet, ServletContext is the application object.
The difference between the two is that application is used in jsp and servletContext is used in servlet.

Create a new jsp file: pageContextDemo02

<h1>The retrieved value is</h1>
<h2>${name1}</h2>
<h2>${name2}</h2>
<h2>${name3}</h2>
<h2>${name4}</h2>

Restart the server. When you first enter demo02.jsp, you find that there is no value. Because demo01 has not been opened, you cannot load the value.

So open demo01 and then demo02, and only "szg3" and "szg4" are found

JVM: parental delegation mechanism

  • Parental delegation mechanism means that when a class loader receives a class loading request, the class loader will first delegate the request to the parent class loader. Repeat until the top layer, using the last one found

  • This is to prevent users from customizing the core class library of Java, such as java.lang.String. Even if they write a jar package and import it, they still call Java's own string

Two implementation methods of page forwarding

  • pageContext.forward("/index.jsp") realizes page Jump in jsp
  • request.getRequestDispatcher("/index.jsp").forward(request,response); Implementing forwarding in the backend servlet

Some illustrative examples of scope

Request: the client sends a request to the server. The generated data is useless after the user reads it. For example, news is useless after the user reads it!

session: the client sends a request to the server, and the generated data is still useful when the user runs out, such as a shopping cart;

application: when the client sends a request to the server, the generated data is used up by one user and may be used by other users, such as chat data;

JSP tag JSTL expression

Remember to import the dependent jar package mentioned earlier

EL expression: common functions of ${}:

  • get data

  • Perform operations

  • Get common objects for web development

  • jsp:include has been mentioned before, which is to splice pages

  • jsp:forward page = "" forward page ""

<%--In the same request Domain, sharing request The properties of the object are equivalent to request.getRequestDispatcher --%>
<jsp:forward page="index.jsp">
    <%--Parameters can also be carried during forwarding--%>
    <jsp:param name="name" value="szg"/>
    <jsp:param name="age" value="19"/>
</jsp:forward>

<%--stay index.jsp In, you can obtain the past value brought by forwarding through the function--%>
<%=request.getParameter("name")%>
<%=request.getParameter("age")%>

JSTL expression

The use of JSTL tag library is to make up for the shortage of HTML tags; It can customize many tags for us to use. The function of tags is the same as that of Java code!

The following tabs are not required to master. You can check them in the rookie tutorial

Format label

SQL tag

XML tag

Core label (master part)

Steps for using JSTL tag library

  • Introducing the corresponding taglib at the beginning of jsp can copy the required JSTL introduction code in the rookie tutorial
  • Use one of the methods
  • In Tomcat, you also need to introduce the JSTL package, otherwise an error will be reported: JSTL parsing error

It seems that after following the steps, 500 errors will appear when running the web page. Crazy God finally finds out the repair method, that is, copy and paste the jar package of jstl and the jar package of standard into the lib directory of tomcat..

Bullet screen some people say that they can still run without copying the package. It may be related to the version of tomcat... Hey...

Try the C: if and C: out tags

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--Remember to import the package,--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="core.jsp" method="get">
    <%-- value Useful el Expressions: from param Object userName Property, --%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="Sign in">
</form>
<%--Judge that if the submitted user name is administrator, the login is successful--%>
<%--Used c:if Judgment label--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="Welcome to the administrator!"/>
</c:if>

<%--Equivalent to output. Remember to add a self closing label--%>
<c:out value="${isAdmin}"/>
</body>
</html>

Try the c:choose c:when tag

<body>
<%--A variable is defined score,The value is 85--%>
<c:set var="score" value="55"/>
<c:choose>
    <c:when test="${score>=90}">
        Your grades are excellent
    </c:when>
    <c:when test="${score>=80}">
        Your grades are average
    </c:when>
    <c:when test="${score>=70}">
        Your grades are good
    </c:when>
    <c:when test="${score<=60}">
        Your grade is a failure
    </c:when>
</c:choose>
</body>

Try the c:forEach tag, which will be commonly used in the future...

<% //Container for java language
    ArrayList<String> people = new ArrayList<>();
    people.add(0,"Zhang San");
    people.add(1,"Li Si");
    people.add(2,"Wang Wu");
    people.add(3,"Zhao Liu");
    people.add(4,"Tian Liu");
    request.setAttribute("list",people);
%>
<%--
var :  Variables traversed each time
items :  Object to traverse
--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"/> <br>
</c:forEach>
<hr>
<c:forEach var="people" items="${list}" begin="1" end="3" step="1" >
    <c:out value="${people}"/> <br>
</c:forEach>

JavaBean

JavaBean - Liao Xuefeng's official website (liaoxuefeng.com)

I feel like a norm....

Connect to the database. I don't know how to download the database. You can watch the previous video... (I also take notes) the user name root password 123456 may need to adjust the time zone and driver. Baidu itself.

Entity class

JavaBean s have specific ways to write:

  • Must have a parameterless construct
  • Property must be privatized
  • There must be a corresponding get/set method;

It is generally used to map ORM with database fields;

ORM: Object Relational Mapping

  • Table - > class
  • Fields – > Properties
  • Line record - > object

First, create a new package com.szg.pojo in the idea and java folder, and create a new people class in the package.

{write the variable name first, then alt+insert, select getter and setter, and then shift+ ⬇ Select all the methods in the window}

Then alt+insert, select constructor, and then shift+ ⬇ Select all the variables in the window, and remember to write a parameterless structure}

In the same step, find a quick way to rewrite tostring,

Create a jdbc database and a people table in the database; id, name, age, address, set id as the main key and increase automatically, and the others are set to be non empty.

If the table cannot be refreshed, did you not click save in the lower right corner after creating the table?? Refresh and reconnect before you can get out.

The entity class people created above often corresponds to the table structure one by one

In the following code, the upper four sentences are completely equivalent to the lower four sentences

<%
    People people =new People();
    people.setId(1);
    people.setName("szg");
    people.getAge();
%>
<%--stay jsp Yes, No java Code implementation class instantiation--%>
<jsp:useBean id="people"class="com.szg.pojo.People"scope="page"/>
<jsp:setProperty name="people" property="id"value="1"/>
<jsp:setProperty name="people" property="name" value="szg"/>
<jsp:getProperty name="people" property="age"/>

MVC three-tier architecture

In the classic MVC mode, m refers to the business model, V refers to the user interface, and C is the controller. The purpose of using MVC is to realize M and V code Separation, so that the same program can use different expressions.

MVC refers to some framework of MVC pattern, which forcibly separates the input, processing and output of an application. Using MVC, the application is divided into three core components: model, view and controller. They each handle their own tasks. The most typical MVC is the pattern of JSP + servlet + javabean.

The old MVC mode: users directly access the control layer, and the control layer can directly operate the database;

servlet – CRUD – > Database
Disadvantages: the program is very bloated, which is not conducive to maintenance

The servlet code includes: processing request, response, view jump, processing JDBC, processing business code, and processing logic code

Architecture: nothing can't be solved by adding one layer!

Program call

JDBC (implement this interface)

Mysql Oracle SqlServer... (various databases from different manufacturers)

New MVC three-tier architecture mode:

Model

  • Business processing: business logic (Service)
  • Data persistence layer: CRUD (Dao - data persistence object)

View

  • Display data

  • Provide link to initiate Servlet request (a, form, img...)

Controller (Servlet)

  • Receive user's request: (req: request parameters, Session information...)

  • Give it to the business layer to process the corresponding code

  • Control view jump

**Login process: * * login - > receive the user's login request - > process the user's request (obtain the user's login parameters, username, password) - -- > give it to the business layer to process the login business (judge whether the user name and password are correct: Transaction) - > Dao layer query whether the user name and password are correct – > database

filter

For example, Shiro security framework technology is implemented with Filter

Filter: filter, which is stuck between the web server and servlet to filter the data of the website;

Examples of use:

  • Deal with Chinese garbled code
  • Dealing with abusive words
  • Login authentication... Etc

Create a new project without importing the java web template, then right-click the project name to add Frameworksupport, and then select web application. Then pom imports dependencies

<dependencies>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
    <dependency>
        <groupId>org.apache.taglibs</groupId>
        <artifactId>taglibs-standard-impl</artifactId>
        <version>1.2.5</version>
        <scope>runtime</scope>
    </dependency>
    <!--Copy the latest version of-->
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
</dependencies>

Then create a package and create a file. At this time, note that there will be many Filter versions for the automatic completion of the implements Filter idea. Select = = javax.servlet version = =

After importing, rewrite the three methods according to the prompts......

Write in CharacterEncodingFilter.java

public class CharacterEncodingFilter implements Filter {
    //Initialization: when the web server is started, it is initialized, waiting for the filter object to appear at any time!
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter initialization");
    }
    //Chain: Chain
          /*
          1. All code in the filter will be executed when filtering specific requests
          2. The filter must continue to travel
              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;charset=UTF-8");

        System.out.println("CharacterEncodingFilter Before execution....");
        chain.doFilter(request,response); //Let our request continue. If we don't write, the program will be intercepted and stopped here!
        System.out.println("CharacterEncodingFilter After execution....");
    }
    //Destroy: when the web server is shut down, the filter is destroyed
    public void destroy() {
        System.out.println("CharacterEncodingFilter Destroy");
    }
}

Write in showservlet.java

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.getWriter().write("Hello");

}

Add the following in web.xml:

<servlet>
    <servlet-name>showservlet</servlet-name>
    <servlet-class>com.szg.filter.showSerlvet</servlet-class>
</servlet>
<!--This goes through the filter-->
<servlet-mapping>
    <servlet-name>showservlet</servlet-name>
    <url-pattern>/servlet</url-pattern>
</servlet-mapping>
<!--This path will not pass through the filter-->
<servlet-mapping>
    <servlet-name>showservlet</servlet-name>
    <url-pattern>/show</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>com.szg.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <!--As long as it is /servlet Any request from will pass through this filter-->
    <url-pattern>/servlet/*</url-pattern>
    <!--Any request will pass through this filter-->
    <!--<url-pattern>/*</url-pattern>-->
</filter-mapping>

After overcoming the error of not supporting Java 5 version, it runs successfully and achieves the expected effect.

monitor

There are many kinds of listeners, which are often determined according to the needs

The following example is an example of a session listener

OnlineCountListener.java file

//Count the number of online people on the current website by counting the number of session s on the website
public class OnlineCountListener implements HttpSessionListener {
    //Create session listener:
    //This event will be triggered once the Session is created!
    public void sessionCreated(HttpSessionEvent se) {
        //Get the Servlet container object, which is equivalent to the tomcat container
        ServletContext ctx = se.getSession().getServletContext();
        //System.out.println(se.getSession().getId());
        int session_sum=0;
        if(ctx.getAttribute("OnlineCount")==null){
            session_sum=1;
        }
        else{
            session_sum=(int)ctx.getAttribute("OnlineCount")+1;
        }
        //Mad gods can also use Integer
        //Int is the basic data type. Integer is a wrapper class of int. it is a class, not a basic data type. In fact, it contains int data. Why use integer, mainly because of the object-oriented idea,
        //Here, it is directly converted from to int type
        ctx.setAttribute("OnlineCount",session_sum);

    }
    //Manually destroy session listening
    //This event will be triggered once the Session is destroyed!
    //There should also be automatic destruction, such as setting the validity period
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();

        int session_sum=0;
        if(ctx.getAttribute("OnlineCount")==null){
            System.out.println("error");
        }
        else{
            session_sum=(int)ctx.getAttribute("OnlineCount")-1;
        }
        //The use of Integer (int) by crazy God is actually out of date. It will be underlined in the idea
        //Int is the basic data type. Integer is a wrapper class of int. it is a class, not a basic data type. In fact, it contains int data. Why use integer, mainly because of the object-oriented idea,
        //Here, it is directly converted from to int type
        ctx.setAttribute("OnlineCount",session_sum);

    }
}

Register listener with web.xml file

<listener>
    <listener-class>com.szg.listener.OnlineCountListener</listener-class>
</listener>

Write a code in index.jsp:

It is also possible to use application, which is equivalent

 <h1>Currently <span style="color: red"><%= application.getAttribute("OnlineCount")
 %> </span>People online</h1>

 <h1>Currently <span style="color: red"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")
 %> </span>People online</h1>

session expiration time: web.xml

<session-config>
    <session-timeout>100</session-timeout>
</session-config>

At first, the browser may create multiple sessions. Mine is 3. The redeployment project is shown in the figure below. Just select Redeploy

Open different browsers at the same time to view the effect:

If you visit both edge and Google browsers at the same time, as shown in the figure

After closing one, the number of online people will not decrease because it closes the browser and does not destroy it manually. They can only wait until they reach the shelf life.

Common applications of filters and listeners

Listener: often used in GUI programming;

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("Happy Mid-autumn Day ");  //Create a new form
        Panel panel = new Panel(null); //panel
        frame.setLayout(null); //Set the layout of the form
        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(0,0,255)); //Set background color
        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(0,255,0)); //Set background color
        frame.add(panel);
        frame.setVisible(true);//so
        //It smells like swing
        //Listen for events. Listen for closing events
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                System.out.println("123");//Click close to output
            }
        });
    }
}

Filter: user login usage;

Users can enter the home page only after logging in! Users cannot enter the home page after logging off!

  1. After the user logs in, put the user's data into Sison
  2. When entering the home page, judge whether the user has logged in; Requirements: implemented in the filter!
  • Create the sys folder in the web directory, and then create a success.jsp to write the page of successful login
<body>
<%
    //After adding this paragraph, you can't enter this page by directly tapping the website
    Object UserSession = request.getSession().getAttribute(constant.USER_SESSION);
    if(UserSession==null){
        response.sendRedirect("/Login.jsp");
    }
%>
<h1>Login success page</h1>
<%-- adopt servlet Registered mappings go to LogoutServlet.java Some background processing of files --%>
<h2><a href="/servlet/logout">cancellation</a></h2>
</body>

<%--                Dividing line                   --%>

<body>
<h1>error!</h1>
<a href="/Login.jsp">return</a>
</body>
  • Create error.jsp in the web directory and write the error page

Be careful not to build it in the sys folder like success!! Using filters later will lead to constant redirection and page crash!!! Be sure to pay attention!!!

You are not allowed to enter the sys directory without logging out or logging in -- from the barrage

<body>
<h1>error!</h1>
<a href="/Login.jsp">return</a>
</body>
  • Create a servlet folder in the com.szg package, and then create a LoginServlet.java in it for processing
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Get the parameters of the front end
        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);
    }
}
  • Create a LogoutServlet.java in the servlet folder for processing
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object user_session = req.getSession().getAttribute(constant.USER_SESSION);
        if(user_session!=null){
            req.getSession().removeAttribute(constant.USER_SESSION);
        } resp.sendRedirect("/Login.jsp"); //Remember to bring a slash
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • Create the Login.jsp file in the web directory and write the login page
<body>
<h1>login interface</h1>
<form action="servlet/login" method="post">
    <input type="text" name="username">
    <input type="submit">
    </form>
</body>
  • Register servlet. Note that the request path must be / servlet/login
<servlet>
    <servlet-name>hello_login</servlet-name>
    <servlet-class>com.szg.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>hello_login</servlet-name>
    <url-pattern>/servlet/login</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>logout</servlet-name>
    <servlet-class>com.szg.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>logout</servlet-name>
    <url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>
  • Write a util package, in which a constant.java file is built to define a constant. If it is a large project, when a variable is frequently used, it can be set as a constant, which can be more convenient for maintenance.
//Defines a constant variable
public final static String  USER_SESSION="USER_SESSION";
//When other java files are used, you can write constant.user directly_ Session is used in some places in the above code.

!!! At this point, the version without filter is completed!! Anyway, I have no problem running(

  • Create a filter
public class SysFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //Strong conversion to subclass is possible
        HttpServletRequest request=(HttpServletRequest) servletRequest;
        HttpServletResponse response=(HttpServletResponse) servletResponse; 
        System.out.println("Once through the filter");
        if(request.getSession().getAttribute(constant.USER_SESSION)==null){
            response.sendRedirect("/error.jsp");
        }
        filterChain.doFilter(request,response);
    }
}
  • Register in xml to filter all files in the sys directory
<filter>
    <filter-name>SysFilter</filter-name>
    <filter-class>com.szg.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SysFilter</filter-name>
    <url-pattern>/sys/*</url-pattern>
</filter-mapping>

JDBC review

Is the devil JDBC?: java is connected to the database!

jar package support is required:

  • java.sql
  • javax.sql
  • MySQL connector Java... Connection driver (must be imported)

Establishment of experimental environment

First, create a table in sqlyog:

CREATE TABLE users(
    id INT PRIMARY KEY,
    `name` VARCHAR(40),
    `password` VARCHAR(40),
    email VARCHAR(60),
    birthday DATE
);
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(1,'Zhang San','123456','zs@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(2,'Li Si','123456','ls@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(3,'Wang Wu','123456','ww@qq.com','2000-01-01');

SELECT	* FROM users;

In IDEA, create a new blank template for Maven project, and then import the dependency in pom.xml

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>

I'm back... After importing 8.0, the later loading driver can't load. Import 5.1. It's a little slow to refresh

<!--mysql Drive of-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

Then connect the database in the IDEA, tick jdbc and load it. You can search the database at the magnifying glass in the upper left corner(

Time zone problem when IDEA connects to the database: Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually solution - dreamer Xiao Cui - blog Garden (cnblogs.com)

Note the following six steps:

public class test_jdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //configuration information
        //useSSL=false to solve the problem that Mysql needs to indicate whether to make an SSL connection in a higher version.
        //Useunicode = true & characterencoding = UTF-8 to solve Chinese garbled code
        String url="jdbc:mysql://localhost:3306/jdbc?useSSL=false&useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "123456";

        //1. Load drive
        Class.forName("com.mysql.jdbc.Driver");
        //2. Connect to the database and represent the database
        Connection connection = DriverManager.getConnection(url, username, password);

        //3. Send SQL object statement to the database, Preparedstatement: CRUD
        // Unsafe sql injection may occur
        Statement statement = connection.createStatement();

        //4. Write SQL directly
        String sql1 = "select * from users";
        String sql2 = "delete from user where id=3";
        //5. Execute SQL query and return a ResultSet: result set z: number of rows affected
        ResultSet rs = statement.executeQuery(sql1);
        int z=statement.executeUpdate(sql2);
        //Loop output result set
        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"));
        }

        //6. Close the connection and release resources (be sure to do it) first on and then off
        rs.close();
        statement.close();
        connection.close();
    }
}


After writing the code, click the green triangle on the left of the line where main is located to run.

Precompiled sql:

public class test_jdbc2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String url="jdbc:mysql://localhost:3306/jdbc?useSSL=false&useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "123456";
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url, username, password);
        //3. Write SQL and use the question mark as a placeholder, which needs to be filled in by yourself
        String sql = "insert into  users(id, name, password, email, birthday) values (?,?,?,?,?);";
        //4. The precompiled data should correspond to the data type as much as possible. For example, the primary key should be unique, and it does not exist in the original table
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1,4);//Assign the value of the first placeholder "1";
        preparedStatement.setString(2,"szg");
        preparedStatement.setString(3,"123456");
        preparedStatement.setString(4,"1105118192@qq.com");
        preparedStatement.setDate(5,new Date(new java.util.Date().getTime()));
        //5. Execute SQL
        int z = preparedStatement.executeUpdate();
        if (z>0){
            System.out.println("Insert successful");
        }
        preparedStatement.close();
        connection.close();
    }
}

JDBC transaction

Transaction: either both succeeded or both failed

ACID principle: atomicity, consistency, persistence and isolation) ensure data security

Open transaction
 Transaction commit commit() Once a transaction is committed, it cannot be modified
 Transaction rollback rollback()
Close transaction

A very classic example is the transfer of money between bank users

==junit test: = = after adding junit dependency package, you can run and test a function method at any time without relying on the main function.

Dependent packages:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
import org.junit.Test;
//When the package import fails, refresh maven
public class test_jdbc3 {
    @Test
    public void test(){
        System.out.println("test");
    }
}

At this point, the test function can run directly and output "test" without starting through main

Create a table first:

CREATE TABLE account(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(10),
`money` FLOAT
);
INSERT INTO account(`name`,`money`) VALUES('A',1000);
INSERT INTO account(`name`,`money`) VALUES('B',1000);
INSERT INTO account(`name`,`money`) VALUES('C',1000);
public class test_jdbc3 {
    @Test
    public void test() {
        String url = "jdbc:mysql://localhost:3306/jdbc?useSSL=false&useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "123456";

        Connection connection = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
             connection = DriverManager.getConnection(url, username, password);

            //Notify the database to start the transaction. If false, auto commit is closed and manual commit is enabled
            connection.setAutoCommit(false);
            String sql = "update account set money = money-100 where name ='A'";
            connection.prepareStatement(sql).executeUpdate();
            //Make an error. If you encounter an error, you will stop the transfer halfway and fail
            //int i = 1/0;
            String sql2 = "update account set money = money+100 where name = 'B'";
            connection.prepareStatement(sql2).executeUpdate();
            connection.commit();//If the above two SQL statements are executed successfully, commit the transaction!
            System.out.println("success");

        } catch (Exception e) { //Happy dolls
            try {
                //If an exception occurs, notify the database to roll back the transaction
                assert connection != null;
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                assert connection != null;
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

SERT INTO account(name,money) VALUES('C',1000);



```java
public class test_jdbc3 {
    @Test
    public void test() {
        String url = "jdbc:mysql://localhost:3306/jdbc?useSSL=false&useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "123456";

        Connection connection = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
             connection = DriverManager.getConnection(url, username, password);

            //Notify the database to start the transaction. If false, auto commit is closed and manual commit is enabled
            connection.setAutoCommit(false);
            String sql = "update account set money = money-100 where name ='A'";
            connection.prepareStatement(sql).executeUpdate();
            //Make an error. If you encounter an error, you will stop the transfer halfway and fail
            //int i = 1/0;
            String sql2 = "update account set money = money+100 where name = 'B'";
            connection.prepareStatement(sql2).executeUpdate();
            connection.commit();//If the above two SQL statements are executed successfully, commit the transaction!
            System.out.println("success");

        } catch (Exception e) { //Happy dolls
            try {
                //If an exception occurs, notify the database to roll back the transaction
                assert connection != null;
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                assert connection != null;
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

Posted by Russ on Fri, 24 Sep 2021 20:10:54 -0700