WEB项目-博客

需求分析

1、博客列表页
博客列表页能够展示当前的博客列表,每一篇博客展示标题,发布时间、摘要。点击标题可以跳转至正文页
2、博客正文页
显示博客详细内容,标题、发布时间、作者、正文
3、博客编辑页
显示一个编辑框,用户可以编辑博客内容并提交给服务器
4、删除博客功能
5、注册登陆功能
登陆成功,才可以对博客进行相关操作,没登陆只能查看

数据库设计

使用数据库存储博客信息,先进行数据库设计,再开发博客列表页,进行数据库设计,重点就是分析出当前需要几张表,以及每个表中有那些字段,这些字段之间的关系等
一般会把建库建表的代码放到一个专属文件里,方便后续随时创建这样的表结构
表1:博客表
blogId 博客id
title 标题
content 正文
postTime 发布时间
userId 作者id
表2:用户表
userId 用户id
username 用户名
password 密码

封装数据库

把JDBC操作数据库的代码进行封装
先封装与数据库建立连接的过程,使用 单例 类封装数据库建立连接的过程
getDataSource()这个方法用来查看当前是否有datasource,如果有的话,就直接返回当前datasource,如果没有,就创建一个datasource进行返回

public class DBUtil {
    private static final String url = "jdbc:mysql://localhost:3306/SNote?characterEncoding=UTF-8&useSSL=false";
    private static final String username = "";//此处填写访问数据库的用户名及密码
    private static final String password = "";

    private static DataSource dataSource = null;
    public static DataSource getDataSource(){
        if (dataSource == null){
            dataSource = new MysqlDataSource();
            ((MysqlDataSource)dataSource).setUrl(url);
            ((MysqlDataSource)dataSource).setUser(username);
            ((MysqlDataSource)dataSource).setPassword(password);
        }
        return dataSource;
    }
    public static Connection getConnection(){
        try {
            return getDataSource().getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void close(Connection connection , PreparedStatement preparedStatement , ResultSet resultSet){
        try {
            if (resultSet != null){
                resultSet.close();
            }
            if (preparedStatement != null){
                preparedStatement.close();
            }
            if (connection != null){
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

创建实体类

创建实体类,此处就需要两个实体类,一个用户,一个博客
博客类

public class Blog {
    private int bolgid;
    private String title;
    private String content;
    private int userId;
    private Timestamp postTime;

    public int getBolgid() {
        return bolgid;
    }

    public void setBolgid(int bolgid) {
        this.bolgid = bolgid;
    }

    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 "Blog{" +
                "bolgid=" + bolgid +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", userId=" + userId +
                ", postTime=" + postTime +
                '}';
    }
}

用户类

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 "User{" +
                "userId=" + userId +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

Dao层

根据需求分析对数据库进行相关操作,也就是创建DAO类
DAO data access object 意为通过这样的类,来操作或访问对应的对象
博客:BlogDao:

public class BlogDao {
    public void insert(Blog blog){
        Connection con = DBUtil.getConnection();
        String  sql = "insert into blog values (null,?,?,?,now())";
        PreparedStatement pre = null;
        try {
            pre = con.prepareStatement(sql);
            pre.setString(1,blog.getTitle());
            pre.setString(2,blog.getContent());
            pre.setInt(3,blog.getUserId());
            pre.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(con,pre,null);
        }
    }
    public void delete(int blogId){
        Connection con = DBUtil.getConnection();
        String  sql = "delete from blog where blogId = ?";
        PreparedStatement pre = null;
        try {
            pre = con.prepareStatement(sql);
            pre.setInt(1,blogId);
            pre.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(con,pre,null);
        }
    }
    public List<Blog> selectAll(){
        List<Blog> blogs = new ArrayList<>();
        Connection con = DBUtil.getConnection();
        String sql = "select * from blog";
        PreparedStatement pre = null;
        ResultSet ret = null;
        try {
            pre = con.prepareStatement(sql);
            ret = pre.executeQuery();
            while (ret.next()){
                Blog blog = new Blog();
                blog.setBolgid(ret.getInt("blogId"));
                blog.setTitle(ret.getString("title"));
                blog.setContent(ret.getString("content"));
                blog.setUserId(ret.getInt("userId"));
                blog.setPostTime(ret.getTimestamp("postTime"));
                blogs.add(blog);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(con,pre,ret);
        }
        return blogs;
    }
    public Blog select(int blogId){
        Connection con = DBUtil.getConnection();
        String sql = "select * from blog where blogId = ?";
        PreparedStatement pre = null;
        ResultSet ret = null;
        try {
            pre = con.prepareStatement(sql);
            pre.setInt(1,blogId);
            ret = pre.executeQuery();
            if (ret.next()){
                Blog blog = new Blog();
                blog.setBolgid(blogId);
                blog.setTitle(ret.getString("title"));
                blog.setContent(ret.getString("content"));
                blog.setUserId(ret.getInt("userId"));
                blog.setPostTime(ret.getTimestamp("postTime"));
                return blog;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(con,pre,ret);
        }
        return null;
    }
}

用户:UserDao

public class UserDao {
    public void insert(User user){
        Connection con = DBUtil.getConnection();
        String sql = "insert into user values (null,?,?)";
        PreparedStatement pre = null;
        try {
            pre = con.prepareStatement(sql);
            pre.setString(1,user.getUsername());
            pre.setString(2,user.getPassword());
            pre.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(con,pre,null);
        }
    }
    public User selectByName(String username){
        Connection con = DBUtil.getConnection();
        String sql = "select * from user where username = ?";
        PreparedStatement pre = null;
        ResultSet ret = null;
        try {
            pre = con.prepareStatement(sql);
            pre.setString(1,username);
            ret = pre.executeQuery();
            while (ret.next()){
                User user = new User();
                user.setUserId(ret.getInt("userId"));
                user.setUsername(ret.getString("username"));
                user.setPassword(ret.getString("password"));
                return user;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(con,pre,ret);
        }
        return null;
    }
    public User findById(int userId){
        Connection con = DBUtil.getConnection();
        String sql = "select * from user where userId = ?";
        PreparedStatement pre = null;
        ResultSet ret = null;
        try {
            pre = con.prepareStatement(sql);
            pre.setInt(1,userId);
            ret = pre.executeQuery();
            while (ret.next()){
                User user = new User();
                user.setUserId(ret.getInt("userId"));
                user.setUsername(ret.getString("username"));
                user.setPassword(ret.getString("password"));
                return user;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(con,pre,ret);
        }
        return null;
    }
}

实现页面

博客列表页面

查看当前系统中存了哪些博客

@WebServlet("/bloglist")
public class BlogListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        BlogDao blogDao = new BlogDao();
        List<Blog> blogs = blogDao.selectAll();
        StringBuilder html = new StringBuilder();
        for (Blog blog: blogs){
            html.append("<div>");
            html.append(String.format("<a href = \"%s\">%s</a>","blogContent?blogId="+blog.getBolgid(),blog.getTitle()));
            html.append(String.format("<div>%s</div>",blog.getPostTime()));
            html.append(String.format("<div>%s</div>",blog.getContent().substring(0,100)+"..."));
            html.append("</div>");
        }
        resp.setContentType("text/html;charset = utf-8");
        resp.getWriter().write(html.toString());
    }
}

这个动态页面是通过代码来生成的,但是用字符串拼接的方式来构造HTML是非常麻烦的,麻烦的主要原因就是当HTML比较复杂的时候,代码就会变得很混乱,而且极难去排查错误,更推荐使用模板来代替原始的字符串拼接,所谓的模板就是一个不完整的HTML文件,这个文件关于关键的信息是不全的,我们可以根据服务器这边的数据,把这个不完整的HTML文件补全,最终形成一个完整的HTML文件,再把这个HTML文件返回给浏览器即可。这样一来,我们的工作量就会少很多
在JAVA中,操作模板有很多现成的库,本项目主要使用Thymeleaf库来完成模板的渲染工作
如果这个渲染工作是在服务器这边完成的,就叫做服务器渲染,在客户端完成的,就叫做客户端渲染
既然用了Thymeleaf,就需要在代码中对Thymeleaf进行初始化。
创建一个engine对象 模板引擎 负责把java中的数据替换到模板中
创建一个resolver对象 解析器 负责找到html模板在哪,并加载到内存中供engine来使用
给resolver设置一些属性,让resolver可以找到模板在哪。首先设置字符集,prefix表示前缀,设定了满足什么条件的文件被加载到内存中做为html模板(也就是目录,从webapp这一层开始算。)、Suffix表示后缀,与前缀意思基本相同
把engine和resolver关联起来
初始化完毕后,就可以使用Thymeleaf来进行渲染了
渲染的时候需要定义一个 数据集合WebContext 的概念 ,WebContext的功能就是把需要替换的数据给收集起来,统一的传给模板引擎

@WebServlet("/bloglist")
public class BlogListServlet extends HttpServlet {
    TemplateEngine engine = new TemplateEngine();
    @Override
    public void init() throws ServletException {

        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());
        resolver.setCharacterEncoding("utf-8");
        resolver.setPrefix("WEB-ING/template/");
        resolver.setSuffix(".html");
        engine.setTemplateResolver(resolver);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        BlogDao blogDao = new BlogDao();
        List<Blog> blogs = blogDao.selectAll();
        WebContext webContext = new WebContext(req,resp,getServletContext());
        webContext.setVariable("blogs",blogs);
        String html = engine.process("blog_list",webContext)
        resp.setContentType("text/html;charset = utf-8");
        resp.getWriter().write(html);
    }
}
博客展示页

从请求中读取出blogId,根据blogId查询到博客,然后再渲染到模板中

@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");
        String blogId = req.getParameter("blogId");
        if (blogId == null || "".equals(blogId)){
            resp.sendError(404);
            return;
        }
        BlogDao blogDao = new BlogDao();
        Blog blog = blogDao.select(Integer.parseInt(blogId));
        if (blog == null){
            resp.sendError(404);
            return;
        }
        UserDao userDao = new UserDao();
        User user = userDao.findById(blog.getUserId());
        if (user == null){
            resp.sendError(404);
            return;
        }
        TemplateEngine engine = (TemplateEngine) getServletContext().getAttribute("engine");
        WebContext webContext = new WebContext(req,resp,getServletContext());
        webContext.setVariable("blog",blog);
        webContext.setVariable("user",user);
        String html = engine.process("blog_content", webContext);
        resp.getWriter().write(html);

    }
}

博客展示页面:

<!doctype html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<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>博客内容页</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body{
            background-color: #f3f3f3;
        }
        .container{
            width: 1100px;
            margin: 0 auto;
            background-color: #fff;
        }
        h3{
            text-align: center;
            font-size: 36px;
            padding: 10px 0;
        }
        .post-time{
            text-align: center;
            color: #9f9f9f;
        }
        .author{
            text-align: center;
            padding: 10px 0;
            color: #9f9f9f;
        }
        .content{
            padding-bottom: 10px;
            text-indent: 40px;
        }

    </style>
</head>
<body>
    <div class="container">
        <h3 th:text="${blog.title}">标题</h3>
        <div class="author" th:text="${user.username}">作者</div>
        <div class="post-time" th:text="${blog.postTime}">2020-02-02 11:11:11</div>
        <div class="content" th:text="${blog.content}">正文</div>
    </div>
</body>
</html>
登陆页面

登陆:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username==null||password==null||"".equals(username)||"".equals(password)){
            resp.sendError(404,"用户名和密码不能为空!!");
            return;
        }
        UserDao userDao = new UserDao();
        User user = userDao.selectByName(username);
        if (user == null){
            resp.sendError(404,"用户名和密码错误!!");
            return;
        }
        if (!user.getPassword().equals(password)){
            resp.sendError(404,"用户名和密码错误!!");
            return;
        }
        HttpSession session = req.getSession(true);
        session.setAttribute("user",user);
        resp.sendRedirect("bloglist");
    }
}

登陆页面:

<!doctype html>
<html lang="en">
<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>用户登录</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: 80%;
        }
        input{
            display: block;
            margin-bottom: 10px;
            width: 300px;
            height: 30px;
            font-size: 20px;
            text-indent: 10px;
        }
        .button{
            color: gainsboro;
            background-color: cornflowerblue;
            border: none;
            border-radius: 5px;
        }
        h3{
            padding: 20px;
            font-size: 30px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <form action="login" method="post">
            <h3>登录</h3>
            用户名: <input type="text" name="username">
            密码: <input type="password" name="password">
            <input type="submit" name="登陆" class="button">
        </form>
    </div>
</body>
</html>
导航栏

实现了登陆页面后,跳转至博客列表页,但是用户没办法确定自己是否登陆,所以可以做一个导航栏,如果没登陆,就显示登陆/注册,如果已经登陆,就显示欢迎xxx
在博客列表页添加:

    <div class="nav">
        <h2>LIT</h2>
        <div class="spacer"></div>
        <a href="login.html" class="navb" th:if="${!isLogin}">登陆</a>
        <div th:if="${!isLogin}">/</div>
        <a href="register.html" class="navb" th:if="${!isLogin}">注册</a>
        <div th:if="${isLogin}" th:text="${'欢迎您,' + user.username}"></div>
    </div>

style属性里添加

	.nav{
	    height: 30px;
	    background-color: aquamarine;
	    color: #9f9f9f;
	    display: flex;
	    align-items: center;
	}
	.navb{
	    color: black;
	}
	.spacer{
	    width: 85%;
	}
	h2{
	    padding-left: 20px;
	}

当前用户是否登陆,需要在博客列表Servlet代码中进行验证

    HttpSession session = req.getSession(false);
    boolean isLogin = false;
    User user = null;
    if (session != null){
        user = (User) session.getAttribute("user");
        if (user != null){
            isLogin = true;
        }
    }
    webContext.setVariable("isLogin",isLogin);
    webContext.setVariable("user",user);
注销

在导航栏应有注销字样,实现注销服务:

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(false);
        if (session == null){
            resp.sendError(404,"当前尚未登陆");
            return;
        }
        session.removeAttribute("user");
        resp.sendRedirect("bloglist");
    }
}

在博客列表页面中添加:

<a href="logout" class="navb" th:if="${isLogin}">注销</a>
注册页面

页面:

<!doctype html>
<html lang="en">
<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>用户注册</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: 80%;
        }
        input{
            display: block;
            margin-bottom: 10px;
            width: 300px;
            height: 30px;
            font-size: 20px;
            text-indent: 10px;
        }
        .button{
            color: gainsboro;
            background-color: cornflowerblue;
            border: none;
            border-radius: 5px;
        }
        h3{
            padding: 20px;
            font-size: 30px;
            text-align: center;
        }
    </style>
</head>
<body>
<div class="container">
    <form action="register" method="post">
        <h3>注册</h3>
        用户名: <input type="text" name="username">
        密码: <input type="password" name="password">
        <input type="submit" name="注册" class="button" value="注册">
    </form>
</div>
</body>
</html>

Servlet类:

@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username == null || password == null || "".equals(username) || "".equals(password) ){
            resp.sendError(404,"用户名或密码为空");
            return;
        }
        UserDao userDao = new UserDao();
        User user = userDao.selectByName(username);
        if (user != null){
            resp.sendError(404,"用户名已存在!!");
            return;
        }
        user = new User();
        user.setPassword(password);
        user.setUsername(username);
        userDao.insert(user);
        resp.sendRedirect("login.html");
    }
}
博客编辑页

这个页面包含两个输入框,一个文章标题,一个文章内容
还有一个提交按钮,点击就可以给服务器发送请求
实现一个Servlet类来处理这个请求
处理请求前先判定用户是否登陆,如果未登录,则不能正常提交
页面:

<!doctype html>
<html lang="en">
<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>博客编辑页</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .title{
            display: block;
            width: 94.8%;
            height: 30px;
            margin: 10px auto;
            font-size: 20px;
            text-indent: 10px;
        }
        textarea{
            display: block;
            width: 95%;
            height: 550px;
            margin: 10px auto;
            font-size: 20px;
            padding: 5px;
            box-sizing: border-box;
        }
        .button{
            display: block;
            width: 80px;
            height: 24px;
            margin-left: 50px;
        }
        h2{
            margin: 5px;
            text-align: center;
        }
        h3{
            text-indent: 30px;
        }
    </style>
</head>
<body>
    <form action="blogedit" method="post">
        <h2>博客编辑页</h2>
        <h3>标题:</h3>
        <input type="text" name="title" class="title">
        <h3>正文:</h3>
        <textarea name="content" ></textarea>
        <input type="submit" value="发布" class="button">
    </form>
</body>
</html>

Servlet类:

@WebServlet("/blogedit")
public class BlogEditServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if (title == null || "".equals(title) || content == null || "".equals(content) ){
            resp.sendError(404,"标题或内容为空!!");
            return;
        }
        HttpSession session = req.getSession(false);
        if (session == null){
            resp.sendError(404,"当前尚未登陆");
            return;
        }
        User user = (User) session.getAttribute("user");
        if (user == null){
            resp.sendError(404,"当前尚未登陆");
            return;
        }
        Blog blog = new Blog();
        blog.setTitle(title);
        blog.setContent(content);
        blog.setUserId(user.getUserId());
        BlogDao blogDao = new BlogDao();
        blog = blogDao.selectOne(user.getUserId());
        resp.sendRedirect("blogContent?blogId=" + blog.getBlogId());
    }
}

导航栏添加写博客按钮

<a href="blog_edit.html" class="navb" th:if="${isLogin}">写博客</a>
删除博客

删除功能主要实现在博客详情页,删除时需要验证用户身份是否和博客发布人相同(只能删除自己发布的博客)
删除功能:


添加至博客详情页:


补充

Thymeleaf用法
首先通过Maven 引入Thymeleaf依赖
实现一个模板文件,也就是不完整的HTML文件,这个文件并不是空出一些信息,而是用Thymeleaf特定的特殊符号进行占位,后面就可以借助Thymeleaf库,从而把获取到的信息填入html文件里
模板如下:

<!doctype html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<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>博客列表页</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body{
            background-color: #f3f3f3;
        }
        .container{
            width: 1100px;
            margin: 0 auto;
            background-color: #fff;
        }
        .title{
            display: block;
            text-align: center;
            color: black;
            font-size: 20px;
            font-weight: 600;
            text-decoration: none;
            padding: 10px 0;
        }
        .post-time{
            text-align: center;
            color: #9f9f9f;
        }
        .desc{
            padding-bottom: 10px;
            text-indent: 40px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="blog" th:each = "blog : ${blogs}">
            <a th:href="${'blogContent?blogId='+blog.blogId}" class="title" th:text="${blog.title}">标题</a>
            <div class="post-time" th:text="${blog.postTime}">2020-02-02 20:20:20</div>
            <div class="desc" th:text="${blog.content}">正文</div>
        </div>
    </div>
</body>
</html>

th:each = "blog : ${blogs}":这是Thymeleaf提供的语法,Thymeleaf中的特殊符号都是由th:开头的,each就表示循环,blog就表示循环中的循环变量,${blogs}就是一个可迭代对象,此处的blogs就是从数据库查找出来后替换到这里的,每次迭代都会取出一个blog,同时创建出一个class为blog的同级div标签(结构相同)
th:text="${blog.title}":th:text就会把变量中的内容按照字符串的方式替换至标签内。
Thymeleaf在替换时首先会判定这个字段是不是public,如果是,就直接取,如果不是,就查看是否存在当前字段的getter方法,如果有,就取出来,如果没有,就报错
通过Thymeleaf在JAVA代码中渲染模板,也称为 服务器渲染


由于初始化Thymeleaf只需要运行一次,而不是每次http请求都要初始化,所以就可以把初始化的代码放入init
但是放入某个init中后,其它Servlet类就不可以使用了,此时就可以使用ServletContext
我们可以把初始化engine的工作交给ServletContext,也可以把engine实例交给ServletContext管理,这样一来,任意Servlet类中都可以都可以拿到ServletContext对象,也就可以拿到engine对象了
借助ServletContext来初始化engine,希望通过ServletContext持有engine引用,进一步的再其它Servlet中获取到这个引用

@WebListener
public class ThymeleafConfig implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        TemplateEngine engine = new TemplateEngine();
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(sce.getServletContext());
        resolver.setCharacterEncoding("utf-8");
        resolver.setPrefix("WEB-INF/template/");
        resolver.setSuffix(".html");
        engine.setTemplateResolver(resolver);

        ServletContext context = sce.getServletContext();
        context.setAttribute("engine",engine);
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

如果在Servlet类中需要使用engine,那么就可以通过ServletContext中获取,如下:

 TemplateEngine engine = (TemplateEngine) getServletContext().getAttribute("engine");

在代码中,异常处理是很常用的
使用if考虑出错情况和捕获异常都可以处理异常,if:先考虑出错i的情况,最后再执行正确的逻辑,捕获异常是,先执行逻辑,出错了再处理。


web程序中,从收到请求到返回响应,这个过程是期望尽可能快的,而数据库操作是相对比较慢的。如果在处理一个请求时,进行了大量的数据库操作,就可能导致相应返回的太慢,浏览器就等待超时了。
浏览器超时时,用户看到的页面就是404

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值