Blog system
The front page is based on html+css+js
The back-end implementation is based on servlet +themthefe
1. Demand analysis
Before software development, first analyze the requirements. Understand what needs to be achieved
Functions to be realized by blog system:
1. Be able to display the current blog list
Blog list page, showing a lot of blogs Each blog contains a title, including the release time and a summary of the blog
Click the title to jump to the blog body page
2 blog body page
Show the details of this blog
The text contains the title, release time and complete text (without displaying pictures)
3. Blog editing page
Displays an edit box where users can edit blog content And submit it to the server
After the submission is successful, the blog background will save the content of the blog, and then you can see the blog in the list page
4. Delete blog function
Add a "delete" button to the blog details page
5. Registration & login function
It is required to log in successfully before publishing the blog~
If you don't log in, you can only view the blog, not publish the blog~
2. Database design operation
Analyze the required tables and the fields of each table
What you need are the blog table and the user table
Blog table blog table
No. blogid title body content publishing time postTime author id userid
User table user
No. userid username password password
create database if not exists RocketBlog; use RocketBlog; drop table if exists blog; create table blog( blogId int primary key auto_increment, title varchar (512), content text, userId int, postTime datetime ); drop table if exists user; create table user( userId int primary key auto_increment, username varchar (50), password varchar (50) );
Encapsulate database operations
Before coding, supplement the directory. Since the introduction, you need to introduce dependencies such as servlet mysql thymelef (page rendering)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>rocket_blog</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.12.RELEASE</version> </dependency> </dependencies> <packaging>war</packaging> <build> <finalName>rocket_blog</finalName> </build> <properties> <encoding>UTF-8</encoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> </project>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> </web-app>
Connecting using jdbc - using singleton (only one instance in the code) mode
package dao; 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 DBUtil { private static final String URL = "jdbc:mysql://127.0.0.1:3306/RocketBlog?characterEncoding=utf8&useSSL=false"; private static final String USERNAME = "root"; private static final String PASSWORD = "wangxp184219"; private static DataSource dataSource = null; // There is also a very serious BUG ~ (multithreading) in this code public static DataSource getDataSource() { // See if the dataSource currently holds an instance // If not, create a new one // If you hold it, you don't have to create a new one and return to the previous one directly if (dataSource == null) { //datasource=new MysqlDataSource(); //((MysqlDataSource)datasource).setUrl(URL); Downward transformation MysqlDataSource mysqlDataSource = new MysqlDataSource(); mysqlDataSource.setUrl(URL); mysqlDataSource.setUser(USERNAME); mysqlDataSource.setPassword(PASSWORD); dataSource = mysqlDataSource; } return dataSource; } public static Connection getConnection() { try { return getDataSource().getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; } public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
Create entity class - >
package dao; public class User { private int userId; private String username; private String password; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "dao.User{" + "userId=" + userId + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; } }
package dao; import java.sql.Date; import java.sql.Timestamp; public class Blog { private int blogId; private String title; private String content; private int userId; // java.sql.Date can only represent date, not hour, minute and second private Timestamp postTime; public int getBlogId() { return blogId; } public void setBlogId(int blogId) { this.blogId = blogId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public Timestamp getPostTime() { return postTime; } public void setPostTime(Timestamp postTime) { this.postTime = postTime; } @Override public String toString() { return "dao.Blog{" + "blogId=" + blogId + ", title='" + title + '\'' + ", content='" + content + '\'' + ", userId=" + userId + ", postTime=" + postTime + '}'; } }
Add, delete, modify and query the data access object for the database
package dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class BlogDao { // Add a blog to the database public void insert(Blog blog) { // 1. Establish a connection with the database server Connection connection = DBUtil.getConnection(); // 2. Assemble SQL String sql = "insert into blog values(null, ?, ?, ?, now())"; PreparedStatement statement = null; try { statement = connection.prepareStatement(sql); statement.setString(1, blog.getTitle()); statement.setString(2, blog.getContent()); statement.setInt(3, blog.getUserId()); // 3. Execute SQL statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { // 4. Close out work DBUtil.close(connection, statement, null); } } // Delete blog from database public void delete(int blogId) { // 1. Establish a connection with the database server Connection connection = DBUtil.getConnection(); // 2. Assemble SQL String sql = "delete from blog where blogId = ?"; PreparedStatement statement = null; try { statement = connection.prepareStatement(sql); statement.setInt(1, blogId); // 3. Execute SQL statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(connection, statement, null); } } // Look up all the blogs from the database // This method is needed when implementing the blog list page // If the number of blogs is small, it doesn't matter If there are many blogs, you should support "paging query" // limit offset public List<Blog> selectAll() { List<Blog> blogs = new ArrayList<Blog>(); // 1. Establish a connection with the database server Connection connection = DBUtil.getConnection(); // 2. Assemble SQL String sql = "select * from blog order by blogId desc"; PreparedStatement statement = null; ResultSet resultSet = null; try { statement = connection.prepareStatement(sql); // 3. Execute SQL resultSet = statement.executeQuery(); // 4. Traverse the result set while (resultSet.next()) { Blog blog = new Blog(); blog.setBlogId(resultSet.getInt("blogId")); blog.setTitle(resultSet.getString("title")); String content = resultSet.getString("content"); if (content.length() > 40) { //A part of the body of the introduction is displayed here content = content.substring(0, 40) + "..."; } blog.setContent(content); blog.setUserId(resultSet.getInt("userId")); blog.setPostTime(resultSet.getTimestamp("postTime")); blogs.add(blog); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(connection, statement, resultSet); } return blogs; } // Query a specified blog from the database // This method is needed to implement the blog details page public Blog selectOne(int blogId) { // 1. Establish connection with database Connection connection = DBUtil.getConnection(); // 2. Assemble SQL String sql = "select * from blog where blogId = ?"; PreparedStatement statement = null; ResultSet resultSet = null; try { statement = connection.prepareStatement(sql); statement.setInt(1, blogId); // 3. Execute SQL resultSet = statement.executeQuery(); // 4. Traverse the result set Either 0 records or only 1 records if (resultSet.next()) { Blog blog = new Blog(); blog.setBlogId(resultSet.getInt("blogId")); blog.setTitle(resultSet.getString("title")); blog.setContent(resultSet.getString("content")); blog.setUserId(resultSet.getInt("userId")); blog.setPostTime(resultSet.getTimestamp("postTime")); return blog; } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(connection, statement, resultSet); } return null; } public static void main(String[] args) { // The above database operation is verified by the code here // 1. Verify insertion // The test here is just a simple "smoke test" Blog blog = new Blog(); blog.setTitle("This is the third blog"); blog.setContent("This is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body Blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body Body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body This is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body, this is the blog body Blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body this is blog body Body this is the blog body this is the blog body this is the blog body this is the blog body this is the blog body"); blog.setUserId(1); BlogDao blogDao = new BlogDao(); blogDao.insert(blog); // 2. Verify search // dao.BlogDao blogDao = new dao.BlogDao(); // List<dao.Blog> blogs = blogDao.selectAll(); // System.out.println(blogs); // dao.Blog blog = blogDao.selectOne(1); // System.out.println(blog); // 3. Verify deletion // dao.BlogDao blogDao = new dao.BlogDao(); // blogDao.delete(1); } }
package dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class UserDao { // When registering, you need to add users to the database // Expected username cannot be duplicated (username is the user name used for login) // When registering (before insert ing), first determine whether the username already exists // If it exists, the subsequent insert operation will not be performed directly // The uniqueness of username does not have to be achieved through database constraints // It can also be done through user code public void insert(User user) { // 1. Establish connection with database Connection connection = DBUtil.getConnection(); // 2. Assemble SQL String sql = "insert into user values(null, ?, ?)"; PreparedStatement statement = null; try { statement = connection.prepareStatement(sql); statement.setString(1, user.getUsername()); statement.setString(2, user.getPassword()); // 3. Execute SQL statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { // 4. Close the connection DBUtil.close(connection, statement, null); } } // When logging in, you need to get the password according to the user name public User selectByName(String username) { // 1. Establish connection with database Connection connection = DBUtil.getConnection(); // 2. Assemble SQL String sql = "select * from user where username = ?"; PreparedStatement statement = null; ResultSet resultSet = null; try { statement = connection.prepareStatement(sql); statement.setString(1, username); // 3. Execute SQL resultSet = statement.executeQuery(); // 4. Traverse the result set The result of the search by name is expected to be a unique record if (resultSet.next()) { User user = new User(); user.setUserId(resultSet.getInt("userId")); user.setUsername(resultSet.getString("username")); user.setPassword(resultSet.getString("password")); return user; } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(connection, statement, resultSet); } return null; } // Check the user information according to the user id // It is needed when displaying bloggers public User selectById(int userId) { // 1. Establish connection with database Connection connection = DBUtil.getConnection(); // 2. Assemble SQL String sql = "select * from user where userId = ?"; PreparedStatement statement = null; ResultSet resultSet = null; try { statement = connection.prepareStatement(sql); statement.setInt(1, userId); // 3. Execute SQL resultSet = statement.executeQuery(); // 4. Traverse the result set There are only 0 or 1 expected results if (resultSet.next()) { User user = new User(); user.setUserId(resultSet.getInt("userId")); user.setUsername(resultSet.getString("username")); user.setPassword(resultSet.getString("password")); return user; } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(connection, statement, resultSet); } return null; } public static void main(String[] args) { UserDao userDao = new UserDao(); // 1. Test insert user function // dao.User user = new dao.User(); // user.setUsername("zhangsan"); // user.setPassword("123"); // userDao.insert(user); // 2. Test search by name // dao.User user = userDao.selectByName("zhangsan"); // System.out.println(user); // 3. Search by test id // dao.User user = userDao.selectById(1); // System.out.println(user); } }
3. Business realization
1. Implement blog list
Lists the blog dynamic pages in the current database, which are generated by code
Although the page is generated dynamically, it is unscientific to construct HTML directly through string splicing in the code!!! Unscientific mainly because it is particularly troublesome, especially when html is complex, the code will be very chaotic and it is difficult to check errors~~
The more recommended method is to use a template to replace the original string splicing ~ to generate HTML, or it can be completed based on a "template"
Thymeleaf to render
If this rendering is done on the server side, it is called "server rendering", which is used here
This rendering may also be done on the browser side It is called "client rendering" (separation of front and back) and is more commonly used
package api; import dao.Blog; import dao.BlogDao; import dao.User; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.WebContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; import java.util.List; @WebServlet("/blogList") public class BlogListServlet extends HttpServlet { @Override public void init() throws ServletException { } private User checkLogin(HttpServletRequest req) { HttpSession session = req.getSession(false); if (session == null) { return null; } User user = (User) session.getAttribute("user"); return user; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 0. Read the current user information from req Determine whether the user logs in User user = checkLogin(req); boolean isLogin = false; if (user != null) { isLogin = true; } // 1. First query the blogs from the database BlogDao blogDao = new BlogDao(); List<Blog> blogList = blogDao.selectAll(); /* for (Blog blog : blogs) { html.append("<div>"); // Title (click the title to jump to the blog details page) // If you want to meet the requirement that you can jump by clicking, the title is an a tag // It is expected to construct a URL with the shape of "blogcontent? Blogid = 1" html.append(String.format("<a href=\"%s\">%s</a>", "blogContent?blogId=" + blog.getBlogId() , blog.getTitle())); // Release time html.append(String.format("<div> %s </div>", blog.getPostTime())); // Blog summary html.append(String.format("<div> %s </div>", blog.getContent().substring(0, 100) + "...")); html.append("</div>"); }*/ // 2. Construct blog page // 1) Render through Thymeleaf When rendering, you need to define the concept of "data set" // The function of WebContext is to collect the data to be replaced and uniformly transmit it to the template engine WebContext webContext = new WebContext(req, resp, getServletContext()); // 2) setVariable can set multiple key value pairs It all depends on how the template code is written // The contents of each ${} in the template need to be set in the webContext webContext.setVariable("blogs", blogList); webContext.setVariable("isLogin", isLogin); webContext.setVariable("user", user); // 3) Render TemplateEngine engine = (TemplateEngine) getServletContext().getAttribute("engine"); String html = engine.process("blog_list", webContext); System.out.println("Content rendered by template: " + html); resp.setContentType("text/html; charset=utf-8"); resp.getWriter().write(html); } }
thymeleaf usage
Introduce dependency first
Implement a template (some key information missing)
The "special symbols" provided by Thymeleaf can "occupy" these key information. Then, with the help of Thymeleaf library, you can replace the title, body and other information obtained in the database with placeholders
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Blog list page</title> <style> /* Clear browser default style */ * { margin: 0; padding: 0; } body { background-color: #f3f3f3; } .container { width: 800px; margin: 0 auto; background-color: #fff; } .title { display: block; text-align: center; color: #000; font-size: 20px; font-weight: 700; text-decoration: none; padding: 10px 0; } .post-time { text-align: center; color: #999aaa; } .desc { padding-bottom: 10px; text-indent: 20px; } .nav { height: 50px; background: #000; color: #fff; display: flex; align-items: center; } .nav-title { padding-left: 10px; } .nav-button { color: #fff; text-decoration: none; padding: 0 10px; } .spacer { width: 55%; } </style> </head> <body> <div class="nav"> <!-- If the user is not logged in, Show not logged in, And show login/Register button --> <!-- If the user is logged in, Show welcome XXX --> <h3 class="nav-title">My blog system</h3> <div class="spacer"></div> <a href="login.html" class="nav-button" th:if="${!isLogin}">land</a> <a href="register.html" class="nav-button" th:if="${!isLogin}">register</a> <div th:if="${isLogin}" th:text="${'welcome' + user.username}"></div> <a href="blog_insert.html" class="nav-button" th:if="${isLogin}">Blog</a> <a href="logout" class="nav-button" th:if="${isLogin}">cancellation</a> </div> <!-- .container All blogs are stored --> <div class="container"> <!-- .blog Corresponding to a blog --> <div class="blog" th:each="blog : ${blogs}"> <!-- each Represents a loop blog Is a cyclic variable --> <a th:href="${'blogContent?blogId=' + blog.blogId}" class="title" th:text="${blog.title}">I'm the title</a> <div class="post-time" th:text="${blog.postTime}">2021-07-11 17:30:00</div> <div class="desc" th:text="${blog.content}">I am the summary of the text...</div> </div> </div> </body> </html>
in noodles of within Allow surface show yes T h y m e l e a f from J a v a generation code in Obtain take reach of change amount this in of t h : e a c h meeting Follow ring Times calendar The content in {} represents the variable obtained by Thymeleaf from Java code ~ th:each here will be iterated The content inside represents the variable obtained by Thymeleaf from Java code. Here, th:each will loop through {blogs} and one blog element will be created at the same time each time a blog element is taken out
The type of blog here is the blog in the code. There are indeed title, posttime and content fields here~~
Thymeleaf determines whether the current fields are public If so, take it directly If not, see if there is a public getter method If so, you can also call the getter method to get the value of the property
If neither of them is, Thymeleaf reported a mistake~~
Rendering templates in java code
First initialize thymeleaf
package config; //import com.sun.xml.internal.ws.api.policy.PolicyResolver; 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 //Implementation listener public class ThymeleafConfig implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // Use this!!! // This method will be initialized after the ServletContext of the current webapp // Execute immediately The initialization of Thymeleaf can be called here!!! // Initialize Thymeleaf // 1) Create an engine to replace the data in Java with the template TemplateEngine engine = new TemplateEngine(); // 2) Create a resolver object (parser) to find out where the html template is and load it into memory // For use by the engine object ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(sce.getServletContext()); // 3) Set some properties for resolver so that it can find the html template resolver.setCharacterEncoding("utf-8"); // Prefix stands for "prefix", which sets what conditions are met for the file to be loaded into memory as an HTML template resolver.setPrefix("/WEB-INF/template/"); // Suffix stands for "suffix" resolver.setSuffix(".html"); // 4) Associate resolver with engine engine.setTemplateResolver(resolver); // Give the initialized engine object to ServletContext for safekeeping ServletContext context = sce.getServletContext(); context.setAttribute("engine", engine); } @Override public void contextDestroyed(ServletContextEvent sce) { //Destroy } }
2. Implement blog details page
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Blog content page</title> <style> /* Clear browser default style */ * { margin: 0; padding: 0; } body { background-color: #f3f3f3; } .container { width: 800px; margin: 0 auto; background-color: #fff; } .title { text-align: center; padding: 10px 0; font-size: 36px; } .author { text-align: center; padding: 10px 0; color: #999aaa; } .post-time { text-align: center; color: #999aaa; } .content { padding: 10px 0; text-indent: 20px; } .nav { height: 50px; background: #000; color: #fff; display: flex; align-items: center; } .nav-title { padding-left: 10px; } .nav-button { color: #fff; text-decoration: none; padding: 0 10px; } .spacer { width: 55%; } </style> </head> <body> <div class="nav"> <!-- If the user is not logged in, Show not logged in, And show login/Register button --> <!-- If the user is logged in, Show welcome XXX --> <h3 class="nav-title">My blog system</h3> <div class="spacer"></div> <a class="nav-button" th:href="${'blogDelete?blogId=' + blog.blogId}">delete</a> </div> <!-- As a container for the entire blog --> <div class="container"> <h3 th:text="${blog.title}" class="title">This is the blog title</h3> <div class="author" th:text="${username}">Xiao Wang</div> <div class="post-time" th:text="${blog.postTime}">2021-07-11 12:00:00</div> <div class="content" th:text="${blog.content}"> This is the body of the blog This is the body of the blog This is the body of the blog This is the body of the blog This is the body of the blog </div> </div> </body> </html>
The servlet realizes that the page jumps through the url, which is a get request
package api; import dao.Blog; import dao.BlogDao; import dao.User; import dao.UserDao; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.WebContext; 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 java.io.IOException; @WebServlet("/blogContent") public class BlogContentServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html; charset=utf-8"); // 1. Read out the blogId from req String blogId = req.getParameter("blogId"); if (blogId == null || "".equals(blogId)) { // /rocket_blog/blogContent => blogId = null // /rocket_blog/blogContent?blogId= blogId = "" // resp. getWriter(). Write ("< H3 > blogid does not exist < / H3 >"); resp.sendError(404, "blogId Parameter error!"); return; } // 2. Query the blog details in the database according to the blogId BlogDao blogDao = new BlogDao(); Blog blog = blogDao.selectOne(Integer.parseInt(blogId)); if (blog == null) { resp.sendError(404, "blogId The specified article does not exist!"); return; } // 3. According to blog Userid find the corresponding Dao User object UserDao userDao = new UserDao(); User user = userDao.selectById(blog.getUserId()); // 4. Render to the template according to the details TemplateEngine engine = (TemplateEngine) getServletContext().getAttribute("engine"); WebContext webContext = new WebContext(req, resp, getServletContext()); webContext.setVariable("blog", blog); webContext.setVariable("username", user.getUsername()); String html = engine.process("blog_content", webContext); // 5. Write the rendered results back to the client resp.getWriter().write(html); } }
A template engine has been initialized in the BlogListServlet It is found that this engine object is also required in the BlogContentServlet
The same engine needs to be shared among multiple servlets~
You can use ServletContext
Give the initialization of engine to ServletContext and the engine instance to ServletContext management
At this time, any Servlet can get the same ServletContext object and the same engine object~
Initialize engine with ServletContext. Initialize engine after the initialization of ServletContext
Holding the reference of engine through ServletContext enables other servlet s to obtain the reference
The initialized code uses Thymeleaf to render the template with the help of the listener (d)~
Create a WebContext object (data set)
You can put the key data you want to replace in the template into the WebContext
3. Blog landing page
1. Login page (two input boxes, user name and password submission button)
2. The login page is a from form. Click Submit Servlet for processing
3. Read the user name and password and look for a match in the database
4. Log in successfully, create a session, and save the user information of the current successful login to the session for subsequent access to the server to identify
Next, when the user visits the blog editing page, the server will know that the user has logged in You can edit it Otherwise, redirect directly to the login page
After realizing the login page, it is found that the current blog list page does not reflect whether the current user has logged in or not~~
A better approach here is to create a "navigation bar". If the user is not logged in, it will show that he is not logged in, and the login / registration button will be displayed
If the user has logged in, "welcome xxx" is displayed
This page allows you to set a static page
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Landing page</title> <style> * { margin: 0; padding: 0; } html, body { height: 100%; } .container { width: 800px; margin: 0 auto; display: flex; justify-content: center; align-items: center; height: 100%; flex-direction: column; } input { display: block; margin-bottom: 10px; width: 315px; height: 35px; font-size: 20px; text-indent: 10px; } .button { color: #fff; background-color: orange; border: none; border-radius: 5px; } h3 { padding: 10px 0; } </style> </head> <body> <div class="container"> <h3>Please log in to the blog system</h3> <form action="login" method="POST"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="Submit" class="button"> </form> </div> </body> </html>
loginServlet
package api; import dao.User; import dao.UserDao; 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("/login") public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setCharacterEncoding("utf-8"); req.setCharacterEncoding("utf-8"); // 1. Read the username and password submitted by the user from req String username = req.getParameter("username"); String password = req.getParameter("password"); if (username == null || "".equals(username) || password == null || "".equals(password)) { resp.sendError(404, "User name or password cannot be empty"); return; } // 2. Search the user information of the specified user name from the database UserDao userDao = new UserDao(); User user = userDao.selectByName(username); if (user == null) { resp.sendError(404, "Wrong user name or password"); return; } if (!password.equals(user.getPassword())) { // Passwords do not match resp.sendError(404, "Wrong user name or password"); return; } // 3. Login succeeded! Create session HttpSession session = req.getSession(true); session.setAttribute("user", user); // 4. Redirect the user page directly to the blog list page resp.sendRedirect("blogList"); } }
4. Logout page
package api; 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("/logout") public class LogoutServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Delete the user data in the current user's session HttpSession session = req.getSession(false); if (session == null) { resp.sendError(404, "Currently not logged in, Cannot log off"); return; } session.removeAttribute("user"); resp.sendRedirect("blogList"); } }
5. Registration page
Realize Wang Cibei's face
1.register.html static page Content and login Html is basically the same
2. Implement a Servlet to process the registration request
a) Read the submitted user name and password
b) Search the database according to the user name and check whether the user name exists c) If the user name does not exist, insert it into the database
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Registration page</title> <style> * { margin: 0; padding: 0; } html, body { height: 100%; } .container { width: 800px; margin: 0 auto; display: flex; justify-content: center; align-items: center; height: 100%; flex-direction: column; } input { display: block; margin-bottom: 10px; width: 315px; height: 35px; font-size: 20px; text-indent: 10px; } .button { color: #fff; background-color: orange; border: none; border-radius: 5px; } h3 { padding: 10px 0; } </style> </head> <body> <div class="container"> <h3>Please register the blog system</h3> <form action="register" method="POST"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="register" class="button"> </form> </div> </body> </html>
package api; import dao.User; import dao.UserDao; 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 java.io.IOException; @WebServlet("/register") public class RegisterServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // If there are no restrictions, the server does not understand the character encoding in utf-8 by default when reading the Parameter req.setCharacterEncoding("utf-8"); // 1. First read the user name and password submitted by the user String username = req.getParameter("username"); String password = req.getParameter("password"); if (username == null || "".equals(username) || password == null || "".equals(password)) { resp.sendError(404, "The submitted user name or password is empty"); return; } // 2. Query the database to see if username exists UserDao userDao = new UserDao(); User existsUser = userDao.selectByName(username); if (existsUser != null) { // User already exists! Prompt registration failed! resp.sendError(404, "User name already exists, login has failed!"); return; } // 3. Structure Dao User object, insert into database User newUser = new User(); newUser.setUsername(username); newUser.setPassword(password); userDao.insert(newUser); // 4. Return a result resp.setContentType("text/html; charset=utf-8"); resp.getWriter().write("<h3>login was successful!</h3>"); } }
6. Blog editing page
1. Create a blog editing page first
This page contains two input boxes: article title and article content
There is also a submit button
Click the submit button to send a POST request to the server
2. Implement a Servlet to handle the POST request
Directly insert the read data into the database Before processing the request, you need to determine whether the user has logged in If you do not log in, you cannot insert the database to ~
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Blog edit page</title> <style> * { margin: 0; padding: 0; } .title { display: block; width: 600px; height: 50px; margin: 10px auto; font-size: 20px; text-indent: 10px; } textarea { display: block; width: 600px; margin: 10px auto; font-size: 16px; padding: 10px; box-sizing: border-box; } .button { display: block; width: 200px; height: 50px; margin: 0 auto; } </style> </head> <body> <form action="blogInsert" method="POST"> <!-- use input Indicates the title of the article --> <input type="text" name="title" class="title"> <!-- Use this input box to represent the text --> <textarea name="content" rows="30"></textarea> <input type="submit" value="Blog" class="button"> </form> </body> </html>
package api; import dao.Blog; import dao.BlogDao; import dao.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("/blogInsert") public class BlogInsertServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); // 0. Determine whether the user has logged in HttpSession session = req.getSession(false); if (session == null) { resp.sendError(404, "Currently not logged in, Cannot post blog!"); return; } User user = (User) session.getAttribute("user"); if (user == null) { resp.sendError(404, "Currently not logged in, Cannot post blog!"); return; } // 1. Read the parameters in the request String title = req.getParameter("title"); String content = req.getParameter("content"); if (title == null || "".equals(title) || content == null || "".equals(content)) { resp.sendError(404, "Title or body is empty"); return; } // 2. Construct Dao according to the read data Blog object and insert it into the database Blog blog = new Blog(); blog.setTitle(title); blog.setContent(content); blog.setUserId(user.getUserId()); BlogDao blogDao = new BlogDao(); blogDao.insert(blog); // 3. Redirect to the blog list page, and you can also directly see the new blog resp.sendRedirect("blogList"); } }
7. Blog deletion
1. The delete button can be placed on the blog list page (there is a delete button next to each blog title)
2. The delete button can also be placed on the blog details page, and a delete button is added at the top of the blog~
1. The delete button can be placed on the blog list page (there is a delete button next to each blog title)
2. The delete button can also be placed on the blog details page, and a delete button is added at the top of the blog~
package api; import dao.Blog; import dao.BlogDao; import dao.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("/blogDelete") public class BlogDeleteServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. Read the blogId to be deleted from req String blogId = req.getParameter("blogId"); if (blogId == null || "".equals(blogId)) { resp.sendError(404, "blogId Empty!"); return; } // 2. Determine the login status of the user. It cannot be deleted without login HttpSession session = req.getSession(false); if (session == null) { resp.sendError(404, "Not currently logged in, Cannot delete!"); return; } User user = (User) session.getAttribute("user"); if (user == null) { resp.sendError(404, "Not currently logged in, Cannot delete!"); return; } // 3. According to the blogId, query the author id of the blogId to see if it is the same as the currently logged in user id // If it is different, it cannot be deleted BlogDao blogDao = new BlogDao(); Blog blog = blogDao.selectOne(Integer.parseInt(blogId)); if (blog == null) { resp.sendError(404, "The current blog does not exist!"); return; } if (blog.getUserId() != user.getUserId()) { resp.sendError(403, "You can't delete other people's blogs!"); return; } // 4. If the users are the same, delete this blog from the database blogDao.delete(Integer.parseInt(blogId)); // 5. Redirect to blog list page resp.sendRedirect("blogList"); } }
Welcome to exchange and correct mistakes!
Source download