Jsp

JSP is a template engine technology that has been facing elimination. JSP has brought great convenience to people in the early years of Web development

But that was a long time ago, and now JSP technology has been abandoned, and I was not going to write something that was not very usable

But given that some of you may still be wondering if you need to know or learn JSP, in this article we’ll take a look at this outdated technology


What is a Jsp

JSP (full name Jakarta Server Pages, formerly known as Java Server Pages) is a dynamic web technology standard created by Sun Microsystems.

Deployed on a Web server, JSP can respond to requests sent by clients and dynamically generate Web pages of HTML, XML, or other format documents based on the request content, and then return them to the requester.

JSP technology takes Java language as script language, provides services for HTTP requests of users, and can deal with complex business requirements together with other Java programs on the server.

JSP will Java code and specific changes in the content embedded in the static page, static page as a template, dynamic generation of part of the content.

JSP introduces XML tags called “JSP actions” to invoke built-in functions; In addition, JSP tag libraries can be created and then used just like standard HTML or XML tags

Tag libraries can enhance functionality and server performance without being limited by cross-platform issues

The JSP file is converted at run time by its compiler into more primitive Servlet code

The JSP compiler can compile JSP files into servlets written in Java code, which can then be compiled by the Java compiler into fast executing binary machine code, or directly into binary code.


In previous articles, we used writer.print() for servlets; Method converts a string to HTML code to facilitate line breaking

// Use Writer to embed a p tag in a page to implement a line break
resp.getWriter().print("<p></p>");
Copy the code

As mentioned earlier, the biggest pain point of servlets is that they need to embed a lot of HTML code into Java code, making it less readable if it is too coupled….

JSP was invented to solve this problem (but not completely, which is why JSP is being used less and less nowadays)


Simple use of Jsp

In order to have direct access to our JSP file, I chose to create a new JSP file under the root path of the Web project, namely here:

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

</body>
</html>
Copy the code

Typically, a new JSP will look like this by default, much like HTML, and we can actually write HTML code in it as well

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<div>
    <h2 style="background-color: aqua"</h2> </div> </body> </ HTML >Copy the code

We can also use a pair of <% to write Java code in

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<div>
    <h2 style="background-color: aqua"</h2> </div> <% PrintWriter writer = response.getwriter (); writer.print("I'm what's printed to the front end in a JSP file.");
%>
</body>
</html>
Copy the code

Here we use Response to get an instance of the PrintWriter object and call print(); The method outputs a string at the front end

This is exactly the same as servlets, and it should come as no surprise that JSPS are actually servlets

Start the server for testing:

There is no problem

The essence of the Jsp

After reading the above tests, I can’t help but feel that JSP is still quite magical, we can use HTML syntax to write HTML and even inline styles in it; You can also write Java code

So why can we call the RESP object in the servlet directly from there? The answer is simple and has been mentioned many times before – JSPS are essentially servlets

Why do we say that? We import a dependency

<dependency>
    <groupId>tomcat</groupId>
    <artifactId>jasper-runtime</artifactId>
    <version>5.5.23</version>
</dependency>
Copy the code

After importing this dependency, we get an abstract class called HttpJspBase

Clicking on this class will reveal that it inherits HttpServlet

public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {... }Copy the code

That means it’s a servlet class, so let’s move on

Open the Tomcat installation path and find a directory called work

Go all the way down, to ROOT, and then down; Until you see a Java file and a class file

These two files are usually prefixed with xxxx_jps. If we preview the Java file, we will see that the Java class inherits HttpJspBase

Ground-breaking discovery. So what are these two files for? I believe that after you read carefully what is JSP, should more or less guess some

Now let’s do a few things to verify that the JSPS mentioned above are essentially servlets;

  • Go to drive C, find your user working directory, and find the hidden directory AppData

  • Click on the Local directory in AppData and find it thereJetBrainsDirectory or.IntelliJIdeaxxxx.xdirectory
  • Go to the Tomcat directory, which will contain the files generated after tomcat is run that you configured. Depending on your environment, find the directory that corresponds to the name of Tomcat used to test JSP files
  • Click on the work directory and proceed to ROOT as above. And find the Java files and class files you want to see
  • Full path example (my environment)

\ AppData \ Local \ JetBrains \ IntelliJIdea2021.1 \ tomcat \ Tomcat_9_0_382_Default_ (Template) _Project_3 \ work \ Catalina \ localhost \ R OOT\org\apache\jsp

Ok, now you see that the JSP you visited generates the corresponding Java file and class file here, and that the Java class also inherits HttpJspBase (meaning it is a servlet)

As we continue to preview the Java file (which can also be opened), you’ll see something like this in its try block

try {
      response.setContentType("text/html; charset=UTF-8");
      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;

      out.write("\r\n");
      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write(" Title\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("<div>\r\n");
      out.write(

r\n"
); out.write("</div>\r\n"); out.write("\r\n"); PrintWriter writer = response.getWriter(); writer.write("I'm what's printed to the front end in a JSP file."); out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>\r\n"); } Copy the code

Our Java code is placed inside the try block intact, while the HTML code is handled by the Servlet class

This is the essence of JSP. When we access a JSP, we are actually accessing the Servlet program generated by that JSP


Register the Jsp in web.xml

From the above we clearly understand that JSP is essentially a servlet, so can we register JSP in our web.xml as a servlet class; How about having a mapping path as well, rather than needing to end with.jsp every time you visit a JSP?

The answer is yes, of course, but first we need to create a directory under web-INF for the JSPS and put the JSPS we need to map into it

<servlet>
    <servlet-name>test</servlet-name>
    <! Instead of using <servlet-class>, we will use <jsp-file> and write the corresponding path.
    <jsp-file>/WEB-INF/page/test.jsp</jsp-file>
</servlet>

<servlet-mapping>
    <servlet-name>test</servlet-name>
    <! Add a mapping path to it -->
    <url-pattern>/test</url-pattern>
</servlet-mapping>
Copy the code

Ok, now let’s restart the server and try to access the path:

We successfully accessed our JSP file


Jsp built-in object

In the previous section, we saw that there is an Out object in the Java class generated by the JSP file and that this object is used frequently

This object is actually a built-in JSP object. Out is just one of many built-in JSP objects. Let’s look at them one by one

final javax.servlet.jsp.PageContext pageContext; // Page context, usually used to store data; The feature is that stored data cannot be accessed across pages
javax.servlet.http.HttpSession session = null;   // There is no need to explain sessions. If you are confused about sessions, you can read the article
final javax.servlet.ServletContext application;  // The context object corresponding to the ServletContext in the servlet
final javax.servlet.ServletConfig config;        // configure, we can call this object in JSP to get the configuration information
javax.servlet.jsp.JspWriter out = null;			 // out, which is the object for output but is not assigned at this point
final java.lang.Object page = this;				 // Current page object
javax.servlet.jsp.JspWriter _jspx_out = null;    
javax.servlet.jsp.PageContext _jspx_page_context = null;

// There are also exception objects and req resp objects passed in as parameters
Copy the code

Most of these objects have a simple assignment in the try block, so you can read it for yourself

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;
Copy the code

Let’s try using these built-in objects in our JSP files; The first is importing the required dependencies

<! Import this dependency to use JSP built-in objects -->
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>jsp-api</artifactId>
    <version>6.0.53</version>
</dependency>
Copy the code

Try using the built-in object OUT in JSP

The < %/*PrintWriter writer = response.getWriter(); Writer. write(" I am what is printed to the front end in a JSP file "); * /

    // Since we can use JSP built-in objects, we do not need to manually obtain the output object as above
    out.write("I'm what's printed to the front end in a JSP file."); % >Copy the code

Testing:

The same effect, printing out the desired string content in the front end


Use built-in objects to store data

In addition, we can also use some built-in objects to store data, such as session, application, etc

<%
    pageContext.setAttribute("name"."Lin"); // Save a piece of data to pageContext that is scoped to the JSP page
    request.setAttribute("age".18); // Save data to the request. This data is scoped for this request (can be forwarded).
    session.setAttribute("gender"."Male"); // Store a single item of data into the session
    application.setAttribute("nickname"."moluu"); // Save data to application. This data is scoped to the entire server% >Copy the code

As shown above, we use four different built-in objects in the JSP file to store several pieces of data with different scopes and life cycles; The details are already in the comments

Let’s try to retrieve this data in another JSP page

<%
    Object nickname = application.getAttribute("nickname");
    // The test method uses the simplest out output, with "" to avoid strong turns
    out.write(nickname+"");
    out.write("<p></P>");
    Object name = pageContext.getAttribute("name");
    out.write(name+"");
    out.write("<p></P>");
    Object age = request.getAttribute("age");
    out.write(age+"");
    out.write("<p></P>");
    Object gender = session.getAttribute("gender");
    out.write(gender+"");
    out.write("<p></P>"); % >Copy the code

You’ll notice that the data stored in requset and pageContext is fetched to null, and that’s the scope problem;

Since the scope of the request is only valid for a single request, the data life cycle is over when we request GET

PageContext Similarly, when we leave the set page, its life cycle is over, so null is fetched (the default value for String is NULL)


We can take this data in set.jsp and run a test:

<%
    pageContext.setAttribute("name"."Lin");
    request.setAttribute("age".18);
    session.setAttribute("gender"."Male");
    application.setAttribute("nickname"."moluu");

    out.write("ok");
%>

<%
    Object nickname = application.getAttribute("nickname");
    // The test method uses the simplest out output, with "" to avoid strong turns
    out.write(nickname+"");
    out.write("<p></P>");
    Object name = pageContext.getAttribute("name");
    out.write(name+"");
    out.write("<p></P>");
    Object age = request.getAttribute("age");
    out.write(age+"");
    out.write("<p></P>");
    Object gender = session.getAttribute("gender");
    out.write(gender+"");
    out.write("<p></P>"); % >Copy the code

As mentioned earlier, the data stored by request can be carried by forwarding, so if we write the code to request forwarding in set.jsp, we can fetch the data stored by Request in other pages

<%
    pageContext.setAttribute("name"."Lin");
    request.setAttribute("age".18);
    session.setAttribute("gender"."Male");
    application.setAttribute("nickname"."moluu");

	// When the page is accessed, the request is forwarded to get.jsp
    pageContext.forward("get"); % >Copy the code

Because of request forwarding, although the page we are in is get.jsp, the actual URL is still localhost:8080/set, which means that our request is not finished. Its stored data has not been destroyed.


PageConeText

In addition to using getAttribute() for different built-in objects; To get the data, we can also use findAttribute() for pageContext; Methods to collect

The function and use of getAttribute() for different built-in objects; It’s the same thing to get the data

<%
    Object nickname = pageContext.findAttribute("nickname");
    // The test method uses the simplest out output, with "" to avoid strong turns
    out.write(nickname+"");
    out.write("<p></P>");
    Object name = pageContext.findAttribute("name");
    out.write(name+"");
    out.write("<p></P>");
    Object age = pageContext.findAttribute("age");
    out.write(age+"");
    out.write("<p></P>");
    Object gender = pageContext.findAttribute("gender");
    out.write(gender+"");
    out.write("<p></P>"); % >Copy the code

PageContext is a special built-in object that we can use not only with findAttribute(); To fetch data from built-in objects in different scopes

We can also setAttribute() for it; The scope method passes in a third parameter

public abstract void setAttribute(String var1, Object var2, int var3);
Copy the code

When we click on pagecontext.class, we see that it has four built-in constants, and these four constants are the third parameter we need

public abstract class PageContext extends JspContext {
    public static final int PAGE_SCOPE = 1;
    public static final int REQUEST_SCOPE = 2;
    public static final int SESSION_SCOPE = 3;
    public static final int APPLICATION_SCOPE = 4; . }Copy the code

So if we look at these constants and we’re pretty much clear, let’s test that out

<%
    pageContext.setAttribute("name"."Lin",PageContext.PAGE_SCOPE);
    pageContext.setAttribute("age".18,PageContext.REQUEST_SCOPE);
    pageContext.setAttribute("gender"."Male",PageContext.SESSION_SCOPE);
    pageContext.setAttribute("nickname"."moluu",PageContext.APPLICATION_SCOPE);

    out.write("ok"); % >Copy the code

There’s no problem. I got what I’m supposed to get, and I got null what I’m not supposed to get, just like before.


The el expression simplifies out

Before, we used the built-in object OUT to print out the corresponding data, but this approach is limited and inefficient; We can simplify it another way

That is, use the following approach

<body>
<%
    Object nickname = pageContext.findAttribute("nickname");
    Object name = pageContext.findAttribute("name");
    Object age = pageContext.findAttribute("age");
    Object gender = pageContext.findAttribute("gender");
%>
<%=nickname%>
<p></p>
<%=name%>
<p></p>
<%=age%>
<p></p>
<%=gender%>
<p></p>
</body>
Copy the code

Writing “=” in a pair of <% can be implemented with out.write(); It’s the same thing. It’s a little weird, but it’s obviously a little bit cleaner; And independent

Of course, this is not the preferred option, as normal development uses more el expressions:

<body>
<%
    Object nickname = pageContext.findAttribute("nickname");
    Object name = pageContext.findAttribute("name");
    Object age = pageContext.findAttribute("age");
    Object gender = pageContext.findAttribute("gender");
%>
<p>${nickname}</p>
<p>${name}</p>
<p>${age}</p>
<p>${gender}</p>
</body>
Copy the code

This is more efficient to write, and can be nested in HTML tags more powerful, in addition to the EL expression values will remove null values from the page, meaning that values that are not fetched are not displayed.


Common Jsp tags

JSP can do much more than that. It can also use specific tags to simplify development

Until then, let’s import some dependencies to prevent errors

<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl-api</artifactId>
    <version>1.2</version>
</dependency>

<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>
Copy the code

include

Include means include, which makes it easy to plug and unplug JSP pages into a specific JSP.

We use it in development to simplify frequent copy-and-paste of common parts such as navigation, sidebar, footer, etc.

Include can be used either statically (directives) or dynamically (actions). If it is a static include, it appends the code from the introduced JSP file to the current file as it is

So sometimes you need to be careful not to introduce something that could cause an error if repeated

As shown, I create two new JSP files in the root directory of the Web project and import page2.jsp using static include in page1.jsp

Java and page1.class files are generated only because the contents of page2.jsp have been translated and inserted into page1.jsp.

If it is a dynamic include, the contents of page2.jsp will not be inserted into page1.jsp and translated into page1_jsp.java, and a page2_jsp.java will exist independently.

Page1_jsp. Java accesses page2_jsp. Java on the server and inserts the returned result into the response.

With dynamic include, we can also set the flush attribute to the < JSP :include> tag to determine whether to flush the output buffer when it is full. The default is false


Static include two (or more) JSP files will only generate a.java file. The variables in these JSP files are shared, so there is no need to pass parameters. Dynamic include, on the other hand, generates multiple.java files, so parameter passing in those JSP files becomes a problem.

Fortunately, JSP provides us with a solution:

<body> <h1> I am the page1</h1> <%-- static include--%> < JSP :include page="page2.jsp"> <%-- Use the < JSP :param> tag to set a parameter --> < JSP :param name="nickname" value="moluu"/>
</jsp:include>
</body>
Copy the code
<body> <h1> I am the page2</h1>
// You can use the request object to fetch it. The default parameter type is String, so you can print it directly through out without forcing it
<h2>nickname: <%=request.getParameter("nickname")%></h2>
</body>
Copy the code

It can also be obtained by the el expression:

<body> <h1> I am the page2</h1>

<h2>nickname: <%=request.getParameter("nickname")%></h2> <%-- >< h3>${param.get()"nickname")} < / h3 > < %, also you can write - > < h3 > nickname: ${param. Nickname} < / h3 > < / body >Copy the code

The effect is the same


forward

The forward tag, which forwards the request, is fairly simple to use, as follows

At this point, we will go to page2.jsp as above, but the URL path will not change

We can also embed the < JSP :param> tag in the < JSP: Forward > tag to carry data when it is forwarded

<body> <h1> I am the page1</h1>
<jsp:forward page="page2.jsp">
    <jsp:param name="nickname" value="Test"/>
</jsp:forward>
</body>
Copy the code

If it is param embedded in the forward tag, there is no way to retrieve this parameter without visiting page1.jsp


JSTL tag libraries

JSP standard Tag Library (JSTL) is a SET of JSP tags, which encapsulates the common core functions of JSP applications.

JSTL supports generic, structured tasks such as iteration, conditional judgment, XML document manipulation, internationalization tags, and SQL tags. In addition, it provides a framework for using custom tags that integrate with JSTL.

JSTL has a lot of stuff, but now that JSPS are dead, these things are actually being used less and less; Because there are alternatives

So I’m not going to spend a lot of time talking about something that’s barely used, but you can finish up by looking at JSP here.

Let’s jump right to some of the core tags most likely to be used:

Before using JSTL-Core, we need to copy a piece of code to introduce

<%-- THE JSTL core tag library introduces --%> <% @taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"% >Copy the code

It’s not enough to introduce the tag library import dependency. Once you test it, there’s a good chance you’ll get 500 exceptions because Tomcat lacks the JSTL dependency

There are two solutions. One is to drop JSTL and Standard dependencies directly into your local Tomcat environment. This will prevent the server from reporting a lack of dependencies at runtime

The other option is to find the output root in your project structure, create a directory in web-INF (lib), and import all dependencies. This way, after your project restarts, the out directory will generate the required dependencies in lib. The server will get the required dependencies from it. I personally prefer to use it this way; But the other is apparently for good.

After solving this small problem we set about writing some simple code in a JSP file

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> < HTML > <head> <title> title </title> </head> <body> <h1> I am the page1</h1> <%-- Write a simple form --%> <form action="page1.jsp" method="get">
    <input type="text" name="name">
    <input type="submit" value="Sure"> </form> <%-- uses JSTLifAdmin --%> <c:if test="${param.name=='admin'}" var="isAdmin"></c:if>
<c:out value="${isAdmin}"></c:out>
</body>
</html>
Copy the code

In fact, as long as you pass the Java basics, there is almost no difficulty in getting started with JSTL; The only thing you need to pay attention to is the syntax

I’m not going to go over it. It’s not very nutritious.

Click the jump


Relax your eyes

Original picture P station address

Painters home page


If I remember correctly, I actually started writing this blog on 13th or 14th of last month

During that time I was lucky enough to get back together with someone I had been separated from for over a year, and to spend a day or two with her

After that, I had to help someone else write something, so I lost the better part of a month, and there was nearly a month between this article and the last one

Now it is relatively idle, I think it will continue to output something in the next month