当前位置:网站首页>Implement a blog system -- using template engine technology

Implement a blog system -- using template engine technology

2022-07-05 14:31:00 Little bits that can't learn binary tree

Main idea :

1) Server render , Based on template engine ( Here we implement the first )

2) Fore and aft end separation , be based on AJAX, The server returns to the front end json Formatted data , The front end is spliced by itself HTML fragment ;

1) Blog list page ( Dynamic pages )<--------- Render the page

1.1 Provide all blog information ( Render each one on the right div Blog ):OperatorBlog Medium SelectAll() Method ------------ From the database

1.2 Provide the personal information of the login :----------> Get the user identity information of the login ------>HttpSession Key value pairs in When clicking on the title of the article , Send... To the server GET request , close BlogID, Visit the blog details page

2) Blog details page ( Dynamic pages )<--------- Render the page

1.1 Provide specific blog data ------> according to blogID adopt OperatorBlog Medium SelectOne Method to query the blog for rendering ------> From the database

1.2 Get the author information in the article ----> according to blogID adopt OperatorBlog Medium SelectorOne Method query to blog, Get blog Medium userID, Then according to the call OperatorUser Medium selectByUserID To find the author of the article -----> From the database

3) Realize blog editing page ( Static page )-------> Send the blog title and content written by the user to the server

First construct a Blog object , Insert data into the database -------->MYSQL

4) Realize the blog login page ( Static page )-------> Submit the user name and password in the input box to the server

4.1 Query user information according to user name ( Query to User object )------>MYSQL

4.2 Put user information (User object ) writes HttpSession Inside

5) Implement the logout function ( There is no separate interface , Just in the navigation bar )

according to a The tag sends a Http Of Get request , Directly delete the user's identity information saved in the session

6) Realize the function of deleting blog ( There is no separate interface , There will be a delete button on the blog details page , The premise is that the currently logged in author is the author of the article )

Send requests like services through hyperlinks , Bring... With you in the request blogID Such a parameter , Then delete the blog ------> Operating the database

1. establish maven project :

1) Let's introduce Servlet Dependence , introduce Thymeleaf and MYSQL Dependence

2) stay main Create under directory webapp Catalog , stay webapp Create... In the directory web.xml file , stay webapp It creates WEB-INF Catalog , Again from WEB-INF It creates template Catalog , Copy all the front pages of the blog system we wrote before

3) Use Smart-Tomact Packaged deployment

2. Design database

We need to store blog information and user identity information in the database

1) Let's create a blog table

Create the database first ----Java200, Blog list : Blog ID, Blog title , Blog text ( Use... In this mediumetext The data range represented is larger than varchar It's going to be longer ), Blog release time , The author of a blog ( Use one ID To mark )

 Create blog tables 
 create table blog(
    blogID int primary key auto_increment,// The identity of each blog 
    title varchar(1024),// Every blog post 
    content mediumtext,// The body of every blog 
    postTime datetime,// The release time of each blog 
    userID int);// The author of every blog 

2) Let's create a user table

The identity of the user ID, User name , User's password , Besides, the user ID in our user table ID And in the blog table userID It can also be associated with foreign keys ;

 create table user(
     userID int,
     name varchar(20),
     password varchar(30));

3) Encapsulate database operations ,JDBC Code , Now let's write some MYSQL Common methods in  

We are Java Create a package called MYSQL

1) We create the first class , be called ConnectionDatabase, Inside the store JDBC link MYSQL Code for , I have written before

package MYSQL;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ConnectionDatabase {
    private static final String url="jdbc:mysql://127.0.0.1:3306/java200?characterEncoding=utf-8&userSSL=true";
    private static final String password="12503487";
    private static  final String user="root";
    public static   DataSource datasource=null;
    public static DataSource getDataSource()
    {
        if(datasource==null)
        {
            synchronized(Object.class)
            {
                if(datasource==null)
                {
                    datasource=new MysqlDataSource();
                    ((MysqlDataSource)datasource).setURL(url);
                    ((MysqlDataSource)datasource).setUser(user);
                    ((MysqlDataSource)datasource).setPassword(password);
                }
            }
        }
        return datasource;
    }
    public static Connection getConnection() throws SQLException {
        return getDataSource().getConnection();
    }
    public void close(ResultSet resultSet, PreparedStatement statement, Connection connection) throws SQLException {
        resultSet.close();
        statement.close();
        connection.close();
    }
}

2. Create entity class , Through each entity class object , To represent a record data in the table ; We create them separately Blog Such classes and User Such a class to represent ; The various attributes in the class correspond to those in the database , And for the attributes inside Set and Get Method ----- They are all classes created according to the content in the database ; We are MYSQL This package , establish Blog and User class ;

1) Pay attention to java Which means time is available timestamp type , You can also use java.sql.Date, But this Date Type can only represent date , When it is impossible to express , branch , Of a second

2) stay MYSQL Middle means time can be used String, But I'm not sure whether the current time is legal , We can also use datetime and timestamp type ( here we are 2038 Years may not be enough )

3. In the process of creating some classes , To pass some JDBC Code to realize some operations of the database ;

1. Let's create the first class , To achieve the right Blog Some operations on objects ;

1) Add a new blog ---- We have the function of publishing articles in the front-end code

2) Get all blog list pages ----- It corresponds to our blog list page , The function is to display all blogs ;

3) According to blog ID You can find the corresponding blog , It is mainly to click in the blog list page to view the full text , You can see the details of a blog post ;

4) According to blog ID To delete the blog ;

5) We can write some test cases to verify our above operations ;

package MYSQL;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;


public class OperateBlog {
    public void insert(Blog blog) throws SQLException, SQLException {
        System.out.println(" Add a new blog ");
        //1 Establish a connection to the database 
        Connection connection=null;
        connection=ConnectionDatabase.getConnection();
        String SQL="insert into blog values(null,?,?,?,?)";
        //2 establish SQL sentence 
        PreparedStatement statement=connection.prepareStatement(SQL);
        statement.setString(1,blog.getTitle());
        statement.setString(2,blog.getContent());
        statement.setTimestamp(3,blog.getPostTime());
        statement.setInt(4,blog.getUserID());
        //3 perform SQL sentence 
        int ret=statement.executeUpdate();
        if(ret==1)
        {
            System.out.println(" New blog succeeded ");
        }else{
            System.out.println(" Failed to add blog ");
        }

   ConnectionDatabase.close(null,statement,connection);

    }
    public List<Blog> SelectAll() throws SQLException {
        System.out.println(" Start looking for all blogs ");
         List<Blog> list=new ArrayList<>();
         Connection connection=ConnectionDatabase.getConnection();
         String SQL="select * from blog";
         PreparedStatement statement=connection.prepareStatement(SQL);
        ResultSet set=statement.executeQuery();
        // Traverse the structure set inside 
        while(set.next())
        {
            Blog blog=new Blog();
            blog.setBlogID(set.getInt("blogID"));
            blog.setTitle(set.getString("title"));
            blog.setContent(set.getString("content"));
            blog.setPostTime(set.getTimestamp("postTime"));
            blog.setUserID(set.getInt("userID"));
            list.add(blog);
        }
     ConnectionDatabase.close(set,statement,connection);
        return list;
    }
    public Blog SelectOne(int blogID) throws SQLException {
        System.out.println(" Start to find the specified blog ");
        Connection connection=null;
        PreparedStatement statement=null;
        connection=ConnectionDatabase.getConnection();
        String SQL="select * from blog where blogID = ?";
        statement=connection.prepareStatement(SQL);
       statement.setInt(1,blogID);
        ResultSet set=statement.executeQuery();

        if(set.next()) {// Don't write the conditions wrong  if(set!=null)
            Blog blog = new Blog();
            // Traverse the result set and , The query here is based on the self incrementing primary key , Or 1 Records are either 0 Bar record ;
            blog.setBlogID(set.getInt("blogID"));
            blog.setTitle(set.getString("title"));
            blog.setContent(set.getString("content"));
            blog.setPostTime(set.getTimestamp("postTime"));
            blog.setUserID(set.getInt("userID"));
            ConnectionDatabase.close(set, statement, connection);
            return blog;
        }
        return null;
    }
    public void DeleteBlog(int blogID) throws SQLException {
        Connection connection=null;
        PreparedStatement statement=null;
        connection=ConnectionDatabase.getConnection();
        String SQL="delete from blog where blogID = ?";
        statement=connection.prepareStatement(SQL);
        statement.setInt(1,blogID);
        int len=statement.executeUpdate();
        if(len==1)
        {
            System.out.println(" Delete successful ");
        }
    }

    public static void main(String[] args) throws SQLException {
       //1 Test the insertion function 
        Blog blog=new Blog();
        blog.setUserID(1);
        blog.setBlogID(1);
        blog.setTitle("ABCDEFG");
        blog.setContent("I am a boy");
        blog.setPostTime(new Timestamp(System.currentTimeMillis()));// Must be java.sql The bag inside 
        //setPostTime There needs to be a Timestamp type , You need it inside new One Timestamp object ,Timestamp The parameter inside is a timestamp 
        // statement The subscript is set from 0 The subscript starts to be set 
        OperateBlog blogdemo=new OperateBlog();
        blogdemo.insert(blog);
        //2. Test and find all blog functions 
        List<Blog> list=blogdemo.SelectAll();
       // System.out.println(list);
        //3 Find the specified blog 
        Blog blog1=blogdemo.SelectOne(1);
        System.out.println(blog1);
    }
}

2. Let's create a second object , To do something about user To operate

1) Add new users , To realize the registration function ( Insert data into the database )

2) Find the user object according to the user name , When logging in, you should find the user object according to the user name , To judge and compare , The password entered in the input box is compared with the found user password , So whether it is correct ;

3) According to the user ID( According to the blog list page ) To find user objects , When we click to view the full text , Show the author's specific identity information on the blog page ( Click on the blog details page );

We need to know , The identity information of the login is displayed on the blog list page , But after clicking on the blog list page , The identity information of the corresponding author of this article is displayed ;

4) When registering , There is only one user name user object , The user name is not repeated ;

package MYSQL;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class OperateUser {
    public void insert(User user) throws SQLException {
         Connection connection=null;
        PreparedStatement statement=null;
        connection=ConnectionDatabase.getConnection();
        String SQL="insert into user values(?,?,?)";
        statement=connection.prepareStatement(SQL);
        statement.setInt(1,user.getUserID());
        statement.setString(2, user.getName());
        statement.setString(3, user.getPassword());
        int len=statement.executeUpdate();
        if(len==1)
        {
            System.out.println(" Insert the success ");
        }else{
            System.out.println(" Insert the failure ");
        }


    }
    public User selectByName(String username) throws SQLException {
          Connection connection=null;
          PreparedStatement statement=null;
          connection=ConnectionDatabase.getConnection();
          String SQL="select * from user where name = ?";
          statement= connection.prepareStatement(SQL);
          statement.setString(1,username);
          ResultSet set=statement.executeQuery();
        if(set.next())
        {
            User user=new User();
            user.setPassword(set.getString("password"));
            user.setName(username);
            user.setUserID(set.getInt("userID"));
            return user;
        }
        return null;
    }
    public User selectByUserID(int userID) throws SQLException {
        Connection connection=null;
        PreparedStatement statement=null;
        connection=ConnectionDatabase.getConnection();
        String SQL="select * from user where userID = ?";
        statement=connection.prepareStatement(SQL);
        statement.setInt(1,userID);
        ResultSet set=statement.executeQuery();
        if(set.next())
        {
            User user=new User();
            user.setUserID(userID);
            user.setName(set.getString("name"));
            user.setPassword(set.getString("password"));
            return user;
        }
        return null;
    }
}

4. At this time, we start to write the operation of realizing the page , We let the server be based on the template engine , To find the data from the database , Return to the page

1) So let's do the initialization first Thymeleaf

2) Implement blog list page

3) Realize the blog details page

4) Realize the blog login page

5) Realize blog editing page  

 1. Initialize the template engine

We need to put the initialization code into ServletContextListener in , And then put TemplateEngine After initialization, put it in ServletContext Inside ;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener// Be sure to add notes 
public class StartThymeleaf implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println(" Start initializing the template engine ");
        //1 establish TemplateEngine Objects and resolver object 
        ServletContext context=servletContextEvent.getServletContext();
        TemplateEngine engine=new TemplateEngine();
        ServletContextTemplateResolver solver=new ServletContextTemplateResolver(context);
        solver.setPrefix("/WEB-INF/template/");
        solver.setSuffix(".html");
        solver.setCharacterEncoding("utf-8");
        //2 take resolver Objects and engine Object to associate 
        engine.setTemplateResolver(solver);
        //3 We will create a good engine Objects in the ServletContext Inside the object 
        context.setAttribute("engine",engine);
        System.out.println(" The operation of initializing the template engine is over ");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

2. Implement blog list page

1) In the blog list page , Every blog we write on the page cannot be a dead data , Instead, you should find every record in the database , Every blog is a class=blog Of div, Besides, no blog has a title , Release time , Content , These attributes are related to those in our database blog The corresponding fields in the table are the same ; We can use it on the front page th:each, According to the server blog Array , Traverse to each one in turn blog, Then build it on our list page ;

2) We can't call all the links on the details page blog2.html, stay href Attribute plus blogID, In this way, our server will know which blog list we are currently visiting ;

3) We put each blog corresponding to view the full text a The label has been changed , This blogID stay QueryString Set it up

  <a href="'blog2.html?blogID='+blog.blogID" class="detail" target="_blank"> View full text &gt;&gt;</a>

When we visit the blog details page of each blog , Bring one blogID, In this way, the server will know which blog we are visiting ;

4) We are writing back end Servlet Code time ,WebServlet The path of the association in , It can contain points , Visit the browser later blog1.html When , It's not a static page , But a dynamically generated page

5) If too much content leads to overflow , Add a scroll bar automatically overflow:auto; If the blog text is too long , Let's cut a paragraph from the blog list page , Part of the ( Just intercept the first few words ), We can operate directly in the database Blog In the category of , When getting all blogs , Determine whether the length of blog content exceeds 90, exceed 90 Characters , Just call subString Method to intercept ; In splicing strings ".......";

When we query the database again , Get the text directly and then judge , If it is too long , Direct truncation

<!--  On the right is the blog list page  -->
        <div class="right">
            <!--  On the right side , We mean blog by blog  -->
            <div class="blog" th:each="blog : ${blogs}">
                <!--  Article title  -->
                <h2 class="title" th:text="${blog.title}"></h2>
                <!--  Release date  -->
                <div class="date" th:text="${blog.postTime}"></div>
                <!--  Article content  -->
             <div class="text" th:text="${blog.content}"></div>
             <!--  View full text button  -->
             <a href="${'blog2.html?blogID'+blog.blogID}" class="detail" target="_blank"> View full text &gt;&gt;</a>
        </div> 
            </div>
 The content here depends on template rendering , One comes from the back end blogs Array or list, We will automatically traverse to each of them blog, Take out every attribute inside , Then go to the rendering operation ;
  OperateBlog operateBlog=new OperateBlog();
   //1 Get a list of all blogs from the database 
        List<Blog> list= null;
        try {
            list = operateBlog.SelectAll();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        resp.setContentType("text/html;charset=utf-8");
        //2 Get the template engine object , Perform page rendering operation 
        ServletContext context=req.getServletContext();
        TemplateEngine engine=(TemplateEngine)context.getAttribute("engine");
   //3 establish WebContext object , Set key value pairs 
        WebContext webContext=new WebContext(req,resp,context);
        webContext.setVariable("blogs",list);
   //4 Rendering 
        String html= engine.process("blog1",webContext);
        resp.getWriter().write(html);

3. Realize the blog details page  

1) On the blog list page , We explicitly specify all blogs , Just get all the blogs , But in the blog details page , We have to rely on a Request in tag BlogID To specify which blog it is , According to blogID To query the database , So we get the details of the blog ; This blogID Is set at QueryString Inside

2) At present, we are still one place away , That is to say, in the current blog details page , What is displayed inside , Not according to Markdown To render , For example, the three-level title here still cannot be displayed normally ;

 <!--  On the right is the blog details page , This div Represents the whole new background of the right version -->
            <div class="right">
<!-- There is no need to write th:each-->
                  <div class="blog">
                    <!--  Article title  -->
                    <h3 th:text="${blog.title}"></h3>
                    <!--  Blog release time  -->
                    <div class="date" th:text="${blog.postTime}">2022 year 12 month 3 Japan </div>
                    <P th:text="${blog.content}"></P>
                </div>        
           </div>
 We hope that in the blog details page , Can pass one blog object , Find the corresponding attribute to render 
  resp.setContentType("text/html;charset=utf-8");
        OperateBlog operateBlog=new OperateBlog();
        String blogID=req.getParameter("blogID");
        if(blogID==""||blogID.equals(""))
        {
            String html="<h3>blogID Field deletion </h3>";
            resp.getWriter().write(html);
        }
        Blog blog= null;
        try {
            blog = operateBlog.SelectOne(Integer.parseInt(blogID));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if(blog==null)
        {
            String html="<h3> According to blog ID The current blog obtained does not exist </h3>";
            resp.getWriter().write(html);
        }
        ServletContext context=req.getServletContext();
        TemplateEngine engine=(TemplateEngine)context.getAttribute("engine");
        WebContext webContext=new WebContext(req,resp,context);
        webContext.setVariable("blog",blog);
        String html=engine.process("blog2",webContext);
        resp.getWriter().write(html);
    }

 4. Achieve blog login interface  

1) Landing page HTML There is no need for dynamic replacement , That is to say, the content is fixed , There is no need for dynamic replacement of templates , There is no content in the page that needs to be dynamically generated

2) Achieve one Servlet To implement the login request ( Static pages are put directly into webapp Inside , Don't put it in the file of the template engine )

3) We also need to fine tune the page , When we click the button , Can send a HTTP request , Inside input Tag plus name attribute , Only one form Form to package ;

4) When implementing the code of the server , The logic we write is like this , Direct use loginServlet To implement

One : First read the user name and password from the request

Two : Then read out from the database according to the user name User, Then compare whether the password is correct , Input correct , Then log in successfully , Put the current user Objects in the HttpSession in , For later use

3、 ... and : After successful login , We directly 302 Redirect to blog list page

5) We want to target the blog list page , Blog details page , Whether you have logged in for a verification , It is agreed here , If you are currently not logged in , You cannot access the blog list page and blog details page , At this time, if you visit , Redirect to the blog landing page ; After this matter, we need to revise what we wrote before , Two Servlet;

Our standard for judging whether users log in is to see whether they can get a suitable one at present session, And you can get the inside user object , It means that the user is logged in ;

6) Put the following code in blog1Servlet and blog2Servlet Inside , When we perform redirection , Be sure to end the current program ;

7) When we restart the server , Direct access blog1.html perhaps blog2.html, Will jump to the blog landing page , Let the current user log in ;

8) Why can we get the login after login user What about objects? ? That's because after we implement the blog landing page , We're on our own httpsession There's one in store user The object is inside ;

Realize the code of specific landing page : 

import MYSQL.OperateUser;
import MYSQL.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //1. Get the parameters in the request 
        resp.setContentType("text.html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        String username=req.getParameter("name");
        String password=req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        if(username==null||password==null||username.equals("")||password.equals(""))
        {  String html="<h3> The user name or password in the current request is missing </h3>";
            resp.getWriter().write(html);
            return;
        }
        OperateUser operateUser=new OperateUser();
        //2 Query users from the database 
        User user=null;
        try {
             user=operateUser.selectByName(username);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //3 check , There is no direct redirection to the login interface , Here are some cases of login failure , We can't find it user Or the passwords do not match 
        if(user==null)
        {
            String html="<h3> Wrong user name or password </h3>";
            resp.getWriter().write(html);
            return;
        }

        if(!user.getPassword().equals(password))
        {
           String html="<h3> Wrong user name or password </h3>";
           resp.getWriter().write(html);
           return;
        }
        //4 hold user The object size is enlarged HttpSession Inside 
        HttpSession httpSession=req.getSession(true);
        httpSession.setAttribute("user",user);
        resp.sendRedirect("blog1.html");
    }
}

Before visiting each page , Code to judge whether the user logs in :

 // Determine whether the current user is logged in 
        HttpSession session=req.getSession(false);
        if(session==null||session.equals(""))
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }
        User userx= (User) session.getAttribute("user");
        if(userx==null)
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }

 1) above HttpSession The object is based on the same SessionID To find objects , When we reach req.getSession() When , We will base on SessionID To find out Session Object ;

2) But at present, we still find some problems , After our successful login , The data in our personal information list on the left is dead , When we go to the blog details page , The author of the article shown is also dead ; The reason why the above information is dead is that we have not implemented the login function before , There is no way to get user information , Now you can log in , Next, you can put the identity information on the current page , Dynamic replacement based on template engine ;

If it is on the blog list page , Then the user information here will display the user information of the current login ;

If the blog details page , Then the user information at this time will display the user information of the current article author ;

Currently, there is no implementation to modify the avatar and gitup This function , These implementations are no different from dynamically replacing user names , It's just that you need to expand fields in the database to save this information ; 

For example, we want to save avatars , You can store the path of some pictures in the database , Then you can return the image path to the front page ;img In the label src Attribute is enough

Let's modify the blog list page first ; 

  What is set here userx It was when we checked the login status just now , from session Read inside user, This userx It is the information of the user who logged in by the current user ;

Every time we restart the server , The one in the server memory that saves the session hash The watch is gone , So the previous login status is gone ( Because this hash table is stored in memory ), The next time our client accesses the server Cookie In the field sessionID The server will not recognize , It can only be regarded as not logged in ;

But in fact, not all session information is in memory ,Servlet The default session is in memory , Want to put hash Tables are stored in files or databases , It should be implemented through code ;

Modify the blog details page : 

The front-end modification method is the same :

  Back end code :

We can't be here webContext It is set from session Read inside user, But according to what we passed on the blog list page before we went again blogID To query users user, This user That's what we need to do with template rendering user;

The above writing is wrong , How can it be based on blogID To query User Well ? The following is true :

   OperateUser operateUser=new OperateUser();
        try {
         User user=operateUser.selectByUserID(blog.getUserID());
            webContext.setVariable("user",user);
        } catch (SQLException e) {
            e.printStackTrace();
        }

5. Implement the logout function  

1) We expect , When we click the logout button , You can exit the login status , Before we judge whether the user logs in , Based on SessionID To find HttpSession object , Then take out the inside user;

2) We must get one user Login is successful , take user Can't get , Or can't get session All login failures ;

3) At present, our logout button is a label , There is a path in it , We can write a Servlet To handle the requests , In the code, we can according to SessionID To find and store in Session Inside User object , And put this User The object was deleted ; stay HttpSession One is provided in removeAttribute() This way ; Then redirect directly to the login interface ;

4) We are on the server side java Create... In the directory deleteServlet To process the logout request ;

  <a href="delete" target="_blank"> Cancellation </a>

import MYSQL.User;

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

@WebServlet("/delete")
public class deleteServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Determine whether the current user is logged in 
        HttpSession session=req.getSession(false);
        if(session==null||session.equals(""))
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }
        User userx= (User) session.getAttribute("user");
        if(userx==null)
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }
        resp.setContentType("text/html;charset=utf-8");
        session.removeAttribute("user");
        // Redirect login interface 
        resp.sendRedirect("blog3.html");
    }
}

6. Realize the blog publishing function

1) Adjust the blog editing page , Our current blog editor page , There is no need for dynamic replacement , Just like the previous login interface , I just have to add form Forms , Just click the submit button at the end , Trigger HTTP request , To submit ;

We will be having input It's labeled with name attribute , It is convenient for the server to get the title of this article , Then the submit button needs to be modified ;

2) In addition, we need to write one by ourselves Servlet For the request to submit a blog , To process ;

3) The function of each modification , Develop new logic , Both need to be matched at the front and rear , This leads to the fact that the interaction between the front and back ends cannot be completely separated

4) however Markdown How to submit the content in the compiler ?

We can do it in id="editor" Of div Add a hidden textarea label , Inside plus name attribute , This thing doesn't need to be displayed , It's just for the following forms to construct data

5) We still need to do one more step , Take us markDown The contents of the compiler are put in textarea Inside , Easy to submit ; We just need to initialize editor When , stay script It's labeled with saveHTMLToTextarea:true, That is, it can make editor.md Save the contents in the edit box to the user's own writing in real time textarea Inside the ; Then you can submit the form further and bring the body of the blog ;

The front-end code : 

 <!--  This is the heart of the blog editing page  -->
   <form action="edit" method="post">
    <div class="edit">
        <div class="writetitle">     
                <input type="text" id="title" name="title">
                <input type="submit" value=" Click post " id="submit">
        </div>
        <div id="editor">
            <textarea name="content" style="display:none"></textarea>
        </div>
   </form>
  
   </div>
   <script>
    // First, initialize the compiler 
    // First create a textinner object 
    //editormd It is equivalent to a function , Generate a editor object 
    // The first parameter is to specify which html In the label , Yuan a html Label Association , The parameter is the corresponding ID;
    var editor=editormd("editor", {
        // The size here must be set here , Can't rely on CSS Set it up 
        width:"100%",
        //  This is calculation makdown The height of the text 
        height:"1000px",
        // The initial content of the editor 
        markdown:"# Write your first blog here ",
        // The path of the plug-in used by the compiler 
        path:"editor.md/lib/",
        saveHTMLToTextarea:true
    });

Back end code : 

import MYSQL.Blog;
import MYSQL.OperateBlog;
import MYSQL.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Timestamp;

@WebServlet("/edit")
public class editServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Determine whether the current user is logged in 
        HttpSession session=req.getSession(false);
        if(session==null||session.equals(""))
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }
        User userx= (User) session.getAttribute("user");
        if(userx==null)
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
//2 Get the title and content of the article in the request 
        String content=req.getParameter("content");
        String title=req.getParameter("title");
 if(content==null||content.equals("")||title==null||title.equals(""))
        {
            String html="<h3> Failed to publish blog , The title or content of the article is empty </h3>";
            resp.getWriter().write(html);
            return;
        }
//3 Construct a blog object , Insert into the database 
        Blog blog=new Blog();
        blog.setContent(content);
// Note that the author of the current article is the current login 
        blog.setUserID(userx.getUserID());
        blog.setTitle(title);
        blog.setPostTime(new Timestamp(System.currentTimeMillis()));
        OperateBlog operateBlog=new OperateBlog();
        try {
            operateBlog.insert(blog);
        } catch (SQLException e) {
            e.printStackTrace();
        }
//4 Redirect to blog list page 
        resp.sendRedirect("blog1.html");
    }
}

7. Now we find , The blog details page shows the original of the blog Markdown Content , Instead of rendered markdown, First level title , The secondary titles are not displayed

One # Will be rendered as a first-class Title , Three # It will be rendered as a three-level Title ( Write on the left , The right side shows the specific rendered results )

We need to adjust our blog details page at this time , At the same time, we also need to introduce editor.md This library , Then there is an operation in this library markdownHTML, The function of this method is to put the original markDown The text is rendered into a HTML

<script>
    // First, initialize the compiler 
    // First create a textinner object 
    //editormd It is equivalent to a function , Generate a editor object 
    // The first parameter is to specify which html In the label , Yuan a html Label Association , The parameter is the corresponding ID;
    var editor=editormd("editor", {
        // The size here must be set here , Can't rely on CSS Set it up 
        width:"100%",
        //  This is calculation makdown The height of the text 
        height:"1000px",
        // The initial content of the editor 
        markdown:"# Write your first blog here ",
        // The path of the plug-in used by the compiler 
        path:"editor.md/lib/",
        saveHTMLToTextarea:true
    });
   
</script>

In the blog details page , There is a code :

<P th:text="${blog.content}"></P> This div It contains markDown Original message 

markdown The original content of , That's it div Inside , We can put this div Take out the contents , Then pass the just markdownToHTML Method ( This method is script Inside the label ) convert , Then give some of the conversion results back to the previous one div in ;

    <div id="content"th:text="${blog.content}"></div>
<script>
            function rendMo(){
                //1 Take out first div What's in it 
                let markDownDiv=document.querySelector("#content");
                let markdown=markDownDiv.innerHTML;
                console.log(markdown);
                //2 hold div The content inside is set to empty 
                markDownDiv.innerHTML="";
                //3 Replace 
                editormd.markdownToHTML('content',{
                    markdown:markdown
                });// First parameter representation ID
            }
            rendMo();
        </script>

8. After we have completed the above adjustments , I found that the current code can indeed be run and rendered , But the background and the previous translucent effect , Seem out of place ;

Here you can give the one just now div Set a pure transparent background (back-groundcolor Inside rgbc Transparency can be set ;

  <div id="content"th:text="${blog.content}" style="background-color:transparent;"></div>
 This style Attribute represents completely transparent , The background you see is the background of a father element ;

  Our previous blog list is not very scientific , Because the new blog appears at the bottom , Usually new blogs are on top , We modified the query statement in the database to find all blogs , add order by postTime desc attribute

9. We implement the function of deleting blogs

1) You can only delete your own blog , For example, A Users cannot delete after logging in B Author's blog

2) We add a delete blog button to the navigation bar in the blog details page , We have clicked on this to delete the blog , It will send a request to the back-end server , Write a Servlet, The server will delete this blog ;

3) If the author of this blog is the user who is currently logged in , Then display the delete button , Otherwise it doesn't show

 <a  target="_blank" th:if="${showdeleteButton}"th:href="${'deleteblog?blogID='+blog.blogID}"></a>

1) We add such code to the front end , First of all, we must judge whether the current login user is the same as the user of the article author , Just use th:if To judge , If the same , Just put showdeleteButton set true, And display it on the page ; Otherwise, it will be set to false;

2) When we click a When labeling , The parameters passed must be brought blogID In this way, we can use the server in the back according to blogID To delete ;

We are blog2Servlet Code modified in :

    webContext.setVariable("showdeleteButton",user.getUserID()==userx.getUserID());

We use deleteblogServlet The code in

import MYSQL.Blog;
import MYSQL.OperateBlog;
import MYSQL.OperateUser;
import MYSQL.User;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;

@WebServlet("/blog2.html")
public class Blog2Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        // Determine whether the current user is logged in 
        HttpSession session=req.getSession(false);
        if(session==null||session.equals(""))
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }
        User userx= (User) session.getAttribute("user");
        if(userx==null)
        {
            System.out.println(" The current user is not logged in ");
            // Not logged in 
            resp.sendRedirect("blog3.html");
            return;
        }
       resp.setContentType("text/html;charset=utf-8");
        OperateBlog operateBlog=new OperateBlog();
        String blogID=req.getParameter("blogID");
        if(blogID==""||blogID.equals(""))
        {
            String html="<h3>blogID Field deletion </h3>";
            resp.getWriter().write(html);
        }
        Blog blog= null;
        try {
            blog = operateBlog.SelectOne(Integer.parseInt(blogID));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if(blog==null)
        {
            String html="<h3> According to blog ID The current blog obtained does not exist </h3>";
            resp.getWriter().write(html);
        }
        ServletContext context=req.getServletContext();
        TemplateEngine engine=(TemplateEngine)context.getAttribute("engine");
        WebContext webContext=new WebContext(req,resp,context);
        OperateUser operateUser=new OperateUser();
        try {
            User user=operateUser.selectByUserID(blog.getUserID());
            webContext.setVariable("user",user);
            webContext.setVariable("showdeleteButton",user.getUserID()==userx.getUserID());
        } catch (SQLException e) {
            e.printStackTrace();
        }

        webContext.setVariable("blog",blog);
        String html=engine.process("blog2",webContext);
        resp.getWriter().write(html);
    }
}

10. Project summary : 

One : Functions that have been implemented :

1) Realize the display of blog list

2) Realize the display of blog details

3) Realized login , User logout , Verification of login status , Display of user information , Writing a blog post , The blog details page can display the rendered markdown effect

4) Realize the function of deleting blog

Two : Functions that are still not implemented

1) User's Avatar function ( Upload your avatar , Different users display different avatars )

2) User gitup Show , At present, it is written dead

3) Support article classification , Create a classification table for the database , Allow users to specify a category when publishing articles

4) Realize editing blog , Modify blog content , Add such a button to the blog details page , Click to enter the blog editing page , Take the content in the blog just now

5) Comment on .......

First modify the front-end code , Then modify the back-end code ;

原网站

版权声明
本文为[Little bits that can't learn binary tree]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207051426582763.html

随机推荐