Template technology and listener

Using template technology

  • Disadvantages of doing it yourself (object - > HTML format):
    1. Code cumbersome
    2. Data and logic are coupled
      Data: html structure
      Logic: loop, string processing, etc
      (1) Error prone
      (2) Once it needs to be modified, it is very troublesome
  • Template engine is to solve the above problem of mixing HTML and Java We can extract the content of HTML and put it into a separate file called template
    give an example:
    Template string in js ` hello ${user.username},Bye! '= > String
    String.format("hello %s,Byte", user.username) => String
  • When using template technology in the web, most of them are not separated from the front and back ends, but the back end directly generates html content!
  • Template file is only an intermediate transaction of resources generated by web application, not a real web resource

Template technology in Web Application

JSP, Thymeleaf (spring boot recommends using Thymeleaf as the default template), FreeMarker

  1. Add dependency
  2. Use in normal classes
    (1) Template engine (TemplateEngin)
    (2) Template resolver
    (3) Data / context for template rendering
    (4) Template file = > path form = > what you really need is the content in the template file
    (5) Result string after template processing

    The root path of the compiled class

All files under the resource root path, at compile time
Will be copied to the root path of the class

public static void main(String[] args) throws UnsupportedEncodingException {
        //1. Create a template engine object
        TemplateEngine engine=new TemplateEngine();

        //2. Create a parser object & & and configure the parser as necessary
        ClassLoaderTemplateResolver resolver=new ClassLoaderTemplateResolver();
        resolver.setTemplateMode(TemplateMode.HTML);
        resolver.setCharacterEncoding("utf-8");//character set
        resolver.setCacheable(false);//Cancel cache
        resolver.setPrefix("templates/"); /// templates under class root path/
        resolver.setSuffix(".html");//Suffix

        //3. Associate the parser object with the engine object
        engine.setTemplateResolver(resolver);

        //4. Prepare the Context object & & and add the data to be rendered
        User user=new User();
        user.uid=1998;
        user.username="Zhang San";
        user.password="123456";
        List<Integer> list= Arrays.asList(1,2,3,4,5);
        Context context=new Context();
        context.setVariable("data",user);//Render the user object with the data name
        context.setVariable("someString","Hello world");//Can be a string
        context.setVariable("number",list);//Can be an array

        //5. Pass in the template name + context to render the template
        String result = engine.process("demo", context);

        //Where is the path of the template file
        //Because this is ClassLoaderTemplateResolver
        //cl is the classloader object when loading the ThymeleafDemo class
        ClassLoader cl = ThymeleafDemo.class.getClassLoader();
        //Splice prefix + template + suffix = > template / demo html
        URL resource = cl.getResource("templates/demo.html");
        System.out.println(URLDecoder.decode(resource.toString(), "UTF-8"));

        //Print the final string
        System.out.println(result);
    }
<!doctype html>
<html lang="zh-hans" xmlns:th="http://www.thymeleleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Template technology demonstration</title>
</head>
<body>
  <h1 th:text="${data.username}">Write whatever you want</h1>
  <h2 th:text="${data.uid}">Will be real uid replace</h2>
  <h2 th:text="${data.password}"></h2>
</body>
</html>

result:

Introduction of template language in thymeleaf

Background knowledge xmlns:th=“ http://www.thymeleaf.org ”, is the XML standard specified namespace (namespace ns)

The th:xxxx xxxx tag is entered under the th namespace (xmlns:th is not written, but there is a warning prompt, which does not affect the use)

All template language features provided by thymeleaf are tags beginning with th:

  1. th:text = "expression language": ${data. Uid} = > uid attribute in user object or getUid() method of user object
    < H1 > (replace here) < / H1 >
    th:text = "Hello! '+ ${data.username}"
  2. th:href = ""https://www.baidu.com/q?wd= ’+${data.username} "replace href attribute in tag
    (except for a few special tags, others replace the default attributes in the tag)
<a href="https://www.qq. com" th:href="' https://www.baidu.com/q?wd= '+ ${data. Username} "> visit Baidu</a>
<img src="/img/demo.jpg" th:src="'https://some.img.com/img?id=' + ${data.uid}">

  1. th:text = "name of each element: ${list}"
<ol>
    <li th:each="s : ${number}">
        <p th:text="${s}"></p>
    </li>
</ol>

  1. Th: if = "": when conditions are met
    Th: unless = "": when conditions are not met
<p th:if="${someString}">have someString</p>
<p th:unless="${someString}">No, someString</p>

  1. Other basic attributes are regarded as directly replacing the tag attributes, such as th:href, th:src, th:class, and th:id

Use templates in web Applications

  1. There is a special parser object (ServletContextResolver)
  2. There is a special Context object (WebContext)
@WebServlet("/template-demo")
public class TemplateDemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. Create a template engine object
        TemplateEngine engine=new TemplateEngine();

        //2. Create a parser object
        ServletContext servletContext = req.getServletContext();//Fixed usage
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(servletContext);
        resolver.setTemplateMode(TemplateMode.HTML);
        resolver.setCharacterEncoding("utf-8");
        resolver.setPrefix("/WEB-INF/templates/");
        resolver.setSuffix(".html");
        resolver.setCacheable(false);

        //3. Associate the parser to the engine object
        engine.setTemplateResolver(resolver);

        //4. Provide the context object to the template engine for this resolution
        WebContext webContext=new WebContext(req,resp,servletContext);

        //5. Prepare the Context data to be put in
        List<String> courseList=getCoursrList();
        webContext.setVariable("courseList",courseList);

        //6. The final body content generated by the template engine
        String responseBody=engine.process("course-list",webContext);

        //7. Fill in the response object
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        resp.getWriter().println(responseBody);

    }

    private List<String> getCoursrList() {
        return Arrays.asList("JavaSE","JavaDS","JavaDB","JavaWeb","JavaTest","JavaEE");
    }
}

<!doctype html>
<html lang="zh-hans" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Course list</title>
</head>
<body>
  <h1>Course list of computer major</h1>
  <ol>
      <li th:each="course : ${courseList}" th:text="${course}"></li>
  </ol>
</body>
</html>

be careful:

  1. Resolver object and Context object are used correctly
  2. Template file placement location
  3. Template file is not a web resource (inaccessible)

Life cycle of each object: (the most efficient)

monitor

  • In the process of Servlet running, there will be some special "opportunities" for us to execute some custom logic The listener is to allow the program ape to "insert code" at these special times
  • Listener mode < - > event driven Java version
    Scenario: registered user
    Registered user - > send new user reward - > generate different tags according to different regions of the user - > send success notification to the user

    Listen to the above - listener

How to write code and build template objects and parsing objects at the right time

  • We hope to initialize our template when the ServletContext has just been initialized
    Since ServletContext will only be initialized once, our template initialization is only done once. For example:
    When the store was just opened, the template was first introduced
    Since the store will only be opened once, the template will only be initialized once
    In the future, each time you sell goods, you can directly use the initialized template object when you open a store

  • The Servlet standard provides methods to execute our code after the initial ServletContext
    1. Add @ WebListener to represent that the class we write is a listener class
    2. Implement the ServletContextListener interface. We are concerned about the events of ServletContext initialization and destruction
    3. Rewrite the contextlnitialized method and execute some code after the ServletContext is initialized


How is the engine object passed?
See whether the ServletContext is the same object, and put the engine object into the ServletContext object to pass

@WebListener
public class ThymeleafConfig implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        //1. Create a template engine object
        TemplateEngine engine=new TemplateEngine();

        //2. Create a parser object
        ServletContext servletContext = sce.getServletContext();//Fixed usage
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(servletContext);
        resolver.setTemplateMode(TemplateMode.HTML);
        resolver.setCharacterEncoding("utf-8");
        resolver.setPrefix("/WEB-INF/templates/");
        resolver.setSuffix(".html");
        resolver.setCacheable(false);

        //3. Associate the parser to the engine object
        engine.setTemplateResolver(resolver);

        //3.5 putting engine objects into ServletContext
        servletContext.setAttribute("engine",engine);
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

@WebServlet("/template")
public class TemplateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
        //4. Provide the context object to the template engine for this resolution
        WebContext webContext=new WebContext(req,resp,servletContext);

        //5. Prepare the Context data to be put in
        List<String> courseList=getCoursrList();
        webContext.setVariable("courseList",courseList);

        //6. The final body content generated by the template engine
        //3.5 get the engine from the ServletContext object
        TemplateEngine engine=(TemplateEngine)servletContext.getAttribute("engine");
        String responseBody=engine.process("course-list",webContext);

        //7. Fill in the response object
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        resp.getWriter().println(responseBody);
    }
    private List<String> getCoursrList() {
        return Arrays.asList("JavaSE","JavaDS","JavaDB","JavaWeb","JavaTest","JavaEE");
    }
}

Keywords: Java servlet

Added by mark_h_uk on Sun, 02 Jan 2022 20:20:09 +0200