JavaWeb 项目 --- 表白墙 和 在线相册

文章目录

  • 一. 案例: 表白墙 (使用模板引擎)
    • 1. 首先创建 maven 项目
    • 2. 创建好模板文件
    • 3. 使用数据库存储数据.创建一个类用于数据库连接
    • 4. 使用 监视器 来初始化 Thymeleaf
    • 5. 编写 Servlet 代码
      • ① 重写 doGet 方法
      • ② 重写 doPost 方法
      • ③ 实现 load 方法
      • ④ 实现 save 方法
    • 6. 注意事项
    • 7. 部署之后 运行截图
  • 二. 案例: 在线相册 (使用模板引擎)
    • 1. 首先创建 maven 项目
    • 2. 创建好模板文件
    • 3. 这是通过访问文件夹里的图片的
    • 4. 使用 监视器 来初始化 Thymeleaf
    • 5. 编写加载页面的 Servlet代码
      • 创建一个类,重写 doGet 方法
      • 实现 loadImage 方法
    • 6. 编写提交图片的 Servlet 代码
      • ① 创建一个类,重写 doPost 方法
    • 7. 注意事项
    • 8. 部署之后 运行截图

一. 案例: 表白墙 (使用模板引擎)

1. 首先创建 maven 项目

引入需要的依赖,创建必要的目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 创建好模板文件

在这里插入图片描述

<!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>表白墙</title></head><body>    <form action="confession" method="post">        <div class="parent">            <div id="wall">表白墙</div>            <div id="remind">输入后点击提交,会将信息显示在表格中</div>            <div class="one"><span class="two">谁:</span><input type="text" class="text" name="from"></div>            <div class="one"><span class="two">对谁:</span><input type="text" class="text" name="to"></div>            <div class="one"><span class="two">说什么:</span><input type="text" class="text" name="message"></div>            <div class="one"><input type="submit" value="提 交" class="press"></div>            <div class="elem" th:each="message : ${messages}">                <span th:text="${message.from}">wz</span>对<span th:text="${message.to}">zw</span>说: <span th:text="${message.message}">wzz</span>            </div>        </div>    </form>        <style>                * {            margin: 0;            padding: 0;        }                .parent {            width: 400px;            margin: 0 auto;        }                #wall {            font-size: 30px;            font-weight: 700;            text-align: center;            margin: 5px;        }                #remind{            font-size:13px;            text-align: center;            color:gray;            margin: 5px;        }                .one {            display: flex;            justify-content: center;            align-items: center;            height: 40px;        }                .two {            width: 100px;            line-height: 40px;        }                .one .text{            width: 200px;            height: 20px;            padding-left: 3px;        }                .one .press{            width: 304px;            height: 40px;            color:white;            background-color: orange;            border-radius: 5px;            border: none;        }                 .one .press:active{            background-color: red;        }                .elem {            text-align: center;            margin: 15px;        }    </style></body></html>

3. 使用数据库存储数据.创建一个类用于数据库连接

ConnectionDB

import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class ConnectionDB {    private static final String URL = "jdbc:mysql://127.0.0.1:3306/confessionWall2?characterEncoding=utf-8&useSSL=true&serverTimezone=UTC";    private static final String USERNAME = "root";    private static final String PASSWORD = "0000";    private static volatile DataSource dataSource = null;    public static DataSource getDataSource() {        if(dataSource == null){            synchronized (ConnectionDB.class){                if(dataSource == null) {                    dataSource = new MysqlDataSource();                    ((MysqlDataSource) dataSource).setURL(URL);                    ((MysqlDataSource) dataSource).setUser(USERNAME);                    ((MysqlDataSource) dataSource).setPassword(PASSWORD);                }            }        }        return dataSource;    }    public static Connection getConnection() throws SQLException {        return getDataSource().getConnection();    }    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();            }        }    }}

4. 使用 监视器 来初始化 Thymeleaf

ThymeleafConfig
注意加上注解

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;@WebListenerpublic class ThymeleafConfig implements ServletContextListener {    @Override    public void contextInitialized(ServletContextEvent servletContextEvent) {        System.out.println("ServletContext 初始化完毕!");        ServletContext context = servletContextEvent.getServletContext();        TemplateEngine engine = new TemplateEngine();        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(context);        resolver.setPrefix("/WEB-INF/template/");        resolver.setSuffix(".html");        resolver.setCharacterEncoding("utf-8");        engine.setTemplateResolver(resolver);        context.setAttribute("engine",engine);    }    @Override    public void contextDestroyed(ServletContextEvent servletContextEvent) {    }}

5. 编写 Servlet 代码

首先创建一个 Confession

class Confession{    public String from;    public String to;    public String message;}

① 重写 doGet 方法

    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        resp.setContentType("text/html;charset=utf-8");        List<Confession> list = load();        TemplateEngine engine = (TemplateEngine) getServletContext().getAttribute("engine");        WebContext webContext = new WebContext(req,resp,getServletContext());        webContext.setVariable("messages",list);        engine.process("confessionwall",webContext, resp.getWriter());    }

② 重写 doPost 方法

        resp.setContentType("text/html;charset=utf-8");        Confession confession = new Confession();        confession.from = req.getParameter("from");        confession.to = req.getParameter("to");        confession.message = req.getParameter("message");        save(confession);        resp.sendRedirect("confession");

③ 实现 load 方法

    private List<Confession> load() {        List<Confession> list = new ArrayList<>();        Connection connection = null;        PreparedStatement statement = null;        ResultSet resultSet = null;        try {            connection = ConnectionDB.getConnection();            String sql = "select * from confession";            statement = connection.prepareStatement(sql);            resultSet = statement.executeQuery();            while(resultSet.next()){                Confession confession = new Confession();                confession.from =resultSet.getString("from");                confession.to = resultSet.getString("to");                confession.message = resultSet.getString("message");                list.add(confession);            }        } catch (SQLException throwables) {            throwables.printStackTrace();        } finally {            ConnectionDB.close(connection,statement,resultSet);        }        return list;    }

④ 实现 save 方法

    private void save(Confession confession) {        Connection connection = null;        PreparedStatement statement = null;        try{            connection = ConnectionDB.getConnection();            String sql = "insert into confession values (?,?,?)";            statement = connection.prepareStatement(sql);            statement.setString(1,confession.from);            statement.setString(2, confession.to);            statement.setString(3,confession.message);            int ret = statement.executeUpdate();            if(ret == 1){                System.out.println("插入成功");            }else{                System.out.println("插入失败");            }        } catch (SQLException throwables) {            throwables.printStackTrace();        } finally {            ConnectionDB.close(connection,statement,null);        }    }

6. 注意事项

  1. 注意模板引擎
    在这里插入图片描述

  2. 注意 乱码的情况,要添加utf-8
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  3. 用数据库的方法存数据,要先创建好数据库

create database confessionWall2;use confessionWall2;create table confession(    `from` varchar(1024),    `to` varchar(1024),    `message` varchar(1024));
  1. 还有一些必要的注解也要加上.
    在这里插入图片描述
    在这里插入图片描述

7. 部署之后 运行截图

浏览器输入对应的URL
在数据库为空的时候界面如下
在这里插入图片描述
在这里插入图片描述
在输入几个数据之后 如下
在这里插入图片描述
此时的数据库中表的内容
在这里插入图片描述
重新部署再进入URL发现数据还是存在.
在这里插入图片描述

二. 案例: 在线相册 (使用模板引擎)

1. 首先创建 maven 项目

引入必要的依赖,已经必要的目录
在这里插入图片描述
在这里插入图片描述

2. 创建好模板文件

image.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>相册</title>    <link rel="stylesheet" href="./style.css"></head><body>    <div class="nav">        <form action="upload" method="POST" enctype="multipart/form-data" >            <input type="file" name="myImage">            <input type="submit" value="上传图片">        </form>    </div>    <div class="parent">            <!-- 第一组图片 -->        <figure class="sample" th:each="image : ${images}">             <img th:src="${image.url}" alt="sample1" />            <figcaption>                <div>                    <h2 th:text="${image.name}">Deconovo</h2>                </div>            </figcaption>            <a th:href="${image.url}"></a>        </figure>    </div>    </body></html>

style.css

@import url(https://fonts.googleapis.com/css?family=Raleway:400,700);*{    margin: 0 auto;    padding: 0 auto;    box-sizing: border-box;}html,body{    width: 100%;    height: calc(100% - 50px);    background-color: #212121;}.parent{    display: flex;    justify-content: center;    align-items: center;    flex-flow: wrap;    margin: 0;    height: 100%;}.nav{    background-color: rgba(255,255,255,0.3);    height: 50px;    width: 100%;    display: flex;    justify-content: left;    align-items: center;}.sample {    font-family: 'Raleway', Arial, sans-serif;    position: relative;    overflow: hidden;    margin: 10px;    min-width: 230px;    max-width: 315px;    width: 100%;    color: #ffffff;    text-align: center;    font-size: 16px;    background-color: #000000;}.sample *,.sample *:before,.sample *:after {    -webkit-box-sizing: border-box;    box-sizing: border-box;        -webkit-transition: all 0.55s ease;    transition: all 0.55s ease;}.sample img {    max-width: 100%;    backface-visibility: hidden;    vertical-align: top;}.sample figcaption {    position: absolute;    bottom: 25px;    right: 25px;    padding: 5px 10px 10px;}.sample figcaption:before,.sample figcaption:after {    height: 2px;    width: 400px;    position: absolute;    content: '';    background-color: #ffffff;}.sample figcaption:before {    top: 0;    left: 0;    -webkit-transform: translateX(100%);    transform: translateX(100%);}.sample figcaption:after {    bottom: 0;    right: 0;    -webkit-transform: translateX(-100%);    transform: translateX(-100%);}.sample figcaption div:before,.sample figcaption div:after {    width: 2px;    height: 300px;    position: absolute;    content: '';    background-color: #ffffff;}.sample figcaption div:before {    top: 0;    left: 0;    -webkit-transform: translateY(100%);    transform: translateY(100%);}.sample figcaption div:after {    bottom: 0;    right: 0;    -webkit-transform: translateY(-100%);    transform: translateY(-100%);}.sample h2,.sample h4 {    margin: 0;    text-transform: uppercase;}.sample h2 {    font-weight: 400;}.sample h4 {    display: block;    font-weight: 700;    background-color: #ffffff;    padding: 5px 10px;    color: #000000;}.sample a {    position: absolute;    top: 0;    bottom: 0;    left: 0;    right: 0;}.sample:hover img,.sample.hover img {    zoom: 1;    filter: alpha(opacity=50);    -webkit-opacity: 0.5;    opacity: 0.5;}.sample:hover figcaption:before,.sample.hover figcaption:before,.sample:hover figcaption:after,.sample.hover figcaption:after,.sample:hover figcaption div:before,.sample.hover figcaption div:before,.sample:hover figcaption div:after,.sample.hover figcaption div:after {    -webkit-transform: translate(0, 0);    transform: translate(0, 0);}.sample:hover figcaption:before,.sample.hover figcaption:before,.sample:hover figcaption:after,.sample.hover figcaption:after {        -webkit-transition-delay: 0.15s;    transition-delay: 0.15s;}

3. 这是通过访问文件夹里的图片的

在webapp下创建一个文件夹 image,里面存放图片.
通过 getServletContext().getRealPath("/image") 来获取绝对路径
在这里插入图片描述

4. 使用 监视器 来初始化 Thymeleaf

这里的代码不变

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;@WebListenerpublic class ThymeleafConfig implements ServletContextListener {    @Override    public void contextInitialized(ServletContextEvent servletContextEvent) {        System.out.println("ServletContext 初始化完毕");        ServletContext context = servletContextEvent.getServletContext();        TemplateEngine engine = new TemplateEngine();        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(context);        resolver.setPrefix("/WEB-INF/template/");        resolver.setSuffix(".html");        resolver.setCharacterEncoding("utf-8");        engine.setTemplateResolver(resolver);        context.setAttribute("engine",engine);    }    @Override    public void contextDestroyed(ServletContextEvent servletContextEvent) {    }}

5. 编写加载页面的 Servlet代码

创建一个 Image 类

class Image {    public String name;    public String url;}

创建一个类,重写 doGet 方法

@WebServlet("/Image")public class onlineImageServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        resp.setContentType("text/html;charset=utf-8");        // 1. 扫描指定路径 /webapp/image 路径        List<Image> images = loadImage();        // 2. 构造到模板页面        TemplateEngine engine = (TemplateEngine) getServletContext().getAttribute("engine");        WebContext webContext = new WebContext(req,resp,getServletContext());        webContext.setVariable("images",images);        String html = engine.process("image",webContext);        resp.getWriter().write(html);    }}

实现 loadImage 方法

注意使用 getRealPath 方法
以及注意使用 file.listFiles()方法

    private List<Image> loadImage() {        List<Image> images = new ArrayList<>();        // 首先得到 /webapp/image 的绝对路径        ServletContext context = this.getServletContext();        // 这里是将 webapp下的目录转换成一个绝对路径        String path = context.getRealPath("/image");        // 根据路径 看里面有哪些图片.        File file = new File(path);        File[] files = file.listFiles();        for(File f:files){            Image image = new Image();            image.name = f.getName();            image.url = "image/"+f.getName();            images.add(image);        }        return images;    }

6. 编写提交图片的 Servlet 代码

① 创建一个类,重写 doPost 方法

注意一定要加上注解@MultipartConfig

import javax.servlet.ServletException;import javax.servlet.annotation.MultipartConfig;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.Part;import java.io.IOException;// 这个注解在上传文件的功能中是必要的@MultipartConfig@WebServlet("/upload")public class UploadServlet extends HttpServlet {    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String path = getServletContext().getRealPath("/image");        Part part = req.getPart("myImage");        part.write(path + "/" + part.getSubmittedFileName());        resp.sendRedirect("Image");    }}

7. 注意事项

  1. 主要是得到文件夹,找到路径的步骤复杂点.重点掌握这几种方法的使用
    在这里插入图片描述
    在这里插入图片描述

  2. 前后端约定好的名称要对应.
    在这里插入图片描述
    在这里插入图片描述

  3. 传文件需要加上注解,否则会报500的错误.@MultipartConfig

8. 部署之后 运行截图

文件中已经存了两个图片,一运行就可以看到这些图片
在这里插入图片描述
点击图片还能放大
在这里插入图片描述
上传图片,上传两个图片
在这里插入图片描述

 
友情链接
鄂ICP备19019357号-22