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

x33g5p2x  于2022-05-05 转载在 Java  
字(13.8k)|赞(0)|评价(0)|浏览(663)

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

1. 首先创建 maven 项目

引入需要的依赖,创建必要的目录

2. 创建好模板文件

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>表白墙</title>
  8. </head>
  9. <body>
  10. <form action="confession" method="post">
  11. <div class="parent">
  12. <div id="wall">表白墙</div>
  13. <div id="remind">输入后点击提交,会将信息显示在表格中</div>
  14. <div class="one"><span class="two">谁:</span><input type="text" class="text" name="from"></div>
  15. <div class="one"><span class="two">对谁:</span><input type="text" class="text" name="to"></div>
  16. <div class="one"><span class="two">说什么:</span><input type="text" class="text" name="message"></div>
  17. <div class="one"><input type="submit" value="提 交" class="press"></div>
  18. <div class="elem" th:each="message : ${messages}">
  19. <span th:text="${message.from}">wz</span><span th:text="${message.to}">zw</span>说: <span th:text="${message.message}">wzz</span>
  20. </div>
  21. </div>
  22. </form>
  23. <style>
  24. /* 去除浏览器默认样式 */
  25. * {
  26. margin: 0;
  27. padding: 0;
  28. }
  29. /* 设置总宽度 */
  30. .parent {
  31. width: 400px;
  32. margin: 0 auto;
  33. }
  34. /* 设置表白墙样式 */
  35. #wall {
  36. font-size: 30px;
  37. font-weight: 700;
  38. text-align: center;
  39. margin: 5px;
  40. }
  41. /* 设置提示信息样式 */
  42. #remind{
  43. font-size:13px;
  44. text-align: center;
  45. color:gray;
  46. margin: 5px;
  47. }
  48. /* 设置弹性布局 */
  49. .one {
  50. display: flex;
  51. justify-content: center;
  52. align-items: center;
  53. height: 40px;
  54. }
  55. /* 设置文字内容 */
  56. .two {
  57. width: 100px;
  58. line-height: 40px;
  59. }
  60. /* 设置输入框 */
  61. .one .text{
  62. width: 200px;
  63. height: 20px;
  64. padding-left: 3px;
  65. }
  66. /* 提交按钮的设置 */
  67. .one .press{
  68. width: 304px;
  69. height: 40px;
  70. color:white;
  71. background-color: orange;
  72. border-radius: 5px;
  73. border: none;
  74. }
  75. /* 设置鼠标点击的时候改变颜色 */
  76. .one .press:active{
  77. background-color: red;
  78. }
  79. /* 提交之后内容的设置 */
  80. .elem {
  81. text-align: center;
  82. margin: 15px;
  83. }
  84. </style>
  85. </body>
  86. </html>

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

ConnectionDB

  1. import com.mysql.cj.jdbc.MysqlDataSource;
  2. import javax.sql.DataSource;
  3. import java.sql.Connection;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. public class ConnectionDB {
  8. private static final String URL = "jdbc:mysql://127.0.0.1:3306/confessionWall2?characterEncoding=utf-8&useSSL=true&serverTimezone=UTC";
  9. private static final String USERNAME = "root";
  10. private static final String PASSWORD = "0000";
  11. private static volatile DataSource dataSource = null;
  12. public static DataSource getDataSource() {
  13. if(dataSource == null){
  14. synchronized (ConnectionDB.class){
  15. if(dataSource == null) {
  16. dataSource = new MysqlDataSource();
  17. ((MysqlDataSource) dataSource).setURL(URL);
  18. ((MysqlDataSource) dataSource).setUser(USERNAME);
  19. ((MysqlDataSource) dataSource).setPassword(PASSWORD);
  20. }
  21. }
  22. }
  23. return dataSource;
  24. }
  25. public static Connection getConnection() throws SQLException {
  26. return getDataSource().getConnection();
  27. }
  28. public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){
  29. if(resultSet != null){
  30. try {
  31. resultSet.close();
  32. } catch (SQLException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. if(statement != null){
  37. try {
  38. statement.close();
  39. } catch (SQLException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. if(connection != null){
  44. try {
  45. connection.close();
  46. } catch (SQLException e) {
  47. e.printStackTrace();
  48. }
  49. }
  50. }
  51. }

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

ThymeleafConfig
注意加上注解

  1. import org.thymeleaf.TemplateEngine;
  2. import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
  3. import javax.servlet.ServletContext;
  4. import javax.servlet.ServletContextEvent;
  5. import javax.servlet.ServletContextListener;
  6. import javax.servlet.annotation.WebListener;
  7. @WebListener
  8. public class ThymeleafConfig implements ServletContextListener {
  9. @Override
  10. public void contextInitialized(ServletContextEvent servletContextEvent) {
  11. System.out.println("ServletContext 初始化完毕!");
  12. ServletContext context = servletContextEvent.getServletContext();
  13. TemplateEngine engine = new TemplateEngine();
  14. ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(context);
  15. resolver.setPrefix("/WEB-INF/template/");
  16. resolver.setSuffix(".html");
  17. resolver.setCharacterEncoding("utf-8");
  18. engine.setTemplateResolver(resolver);
  19. context.setAttribute("engine",engine);
  20. }
  21. @Override
  22. public void contextDestroyed(ServletContextEvent servletContextEvent) {
  23. }
  24. }

5. 编写 Servlet 代码

首先创建一个 Confession

  1. class Confession{
  2. public String from;
  3. public String to;
  4. public String message;
  5. }

① 重写 doGet 方法

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

② 重写 doPost 方法

  1. resp.setContentType("text/html;charset=utf-8");
  2. Confession confession = new Confession();
  3. confession.from = req.getParameter("from");
  4. confession.to = req.getParameter("to");
  5. confession.message = req.getParameter("message");
  6. save(confession);
  7. resp.sendRedirect("confession");

③ 实现 load 方法

  1. private List<Confession> load() {
  2. List<Confession> list = new ArrayList<>();
  3. Connection connection = null;
  4. PreparedStatement statement = null;
  5. ResultSet resultSet = null;
  6. try {
  7. connection = ConnectionDB.getConnection();
  8. String sql = "select * from confession";
  9. statement = connection.prepareStatement(sql);
  10. resultSet = statement.executeQuery();
  11. while(resultSet.next()){
  12. Confession confession = new Confession();
  13. confession.from =resultSet.getString("from");
  14. confession.to = resultSet.getString("to");
  15. confession.message = resultSet.getString("message");
  16. list.add(confession);
  17. }
  18. } catch (SQLException throwables) {
  19. throwables.printStackTrace();
  20. } finally {
  21. ConnectionDB.close(connection,statement,resultSet);
  22. }
  23. return list;
  24. }

④ 实现 save 方法

  1. private void save(Confession confession) {
  2. Connection connection = null;
  3. PreparedStatement statement = null;
  4. try{
  5. connection = ConnectionDB.getConnection();
  6. String sql = "insert into confession values (?,?,?)";
  7. statement = connection.prepareStatement(sql);
  8. statement.setString(1,confession.from);
  9. statement.setString(2, confession.to);
  10. statement.setString(3,confession.message);
  11. int ret = statement.executeUpdate();
  12. if(ret == 1){
  13. System.out.println("插入成功");
  14. }else{
  15. System.out.println("插入失败");
  16. }
  17. } catch (SQLException throwables) {
  18. throwables.printStackTrace();
  19. } finally {
  20. ConnectionDB.close(connection,statement,null);
  21. }
  22. }

6. 注意事项

  1. 注意模板引擎

  1. 注意 乱码的情况,要添加utf-8

  1. 用数据库的方法存数据,要先创建好数据库
  1. create database confessionWall2;
  2. use confessionWall2;
  3. create table confession(
  4. `from` varchar(1024),
  5. `to` varchar(1024),
  6. `message` varchar(1024)
  7. );
  1. 还有一些必要的注解也要加上.

7. 部署之后 运行截图

浏览器输入对应的URL
在数据库为空的时候界面如下

在输入几个数据之后 如下

此时的数据库中表的内容

重新部署再进入URL发现数据还是存在.

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

1. 首先创建 maven 项目

引入必要的依赖,已经必要的目录

2. 创建好模板文件

image.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>相册</title>
  6. <link rel="stylesheet" href="./style.css">
  7. </head>
  8. <body>
  9. <div class="nav">
  10. <form action="upload" method="POST" enctype="multipart/form-data" >
  11. <input type="file" name="myImage">
  12. <input type="submit" value="上传图片">
  13. </form>
  14. </div>
  15. <div class="parent">
  16. <!-- 第一组图片 -->
  17. <figure class="sample" th:each="image : ${images}">
  18. <img th:src="${image.url}" alt="sample1" />
  19. <figcaption>
  20. <div>
  21. <h2 th:text="${image.name}">Deconovo</h2>
  22. </div>
  23. </figcaption>
  24. <a th:href="${image.url}"></a>
  25. </figure>
  26. </div>
  27. </body>
  28. </html>

style.css

  1. /* 引入文字样式库 */
  2. @import url(https://fonts.googleapis.com/css?family=Raleway:400,700);
  3. *{
  4. margin: 0 auto;
  5. padding: 0 auto;
  6. box-sizing: border-box;
  7. }
  8. html,body{
  9. width: 100%;
  10. height: calc(100% - 50px);
  11. background-color: #212121;
  12. }
  13. .parent{
  14. display: flex;
  15. justify-content: center;
  16. align-items: center;
  17. flex-flow: wrap;
  18. margin: 0;
  19. height: 100%;
  20. }
  21. .nav{
  22. background-color: rgba(255,255,255,0.3);
  23. height: 50px;
  24. width: 100%;
  25. display: flex;
  26. justify-content: left;
  27. align-items: center;
  28. }
  29. /* sample 部分的整体样式 */
  30. .sample {
  31. font-family: 'Raleway', Arial, sans-serif;
  32. position: relative;
  33. overflow: hidden;
  34. margin: 10px;
  35. min-width: 230px;
  36. max-width: 315px;
  37. width: 100%;
  38. color: #ffffff;
  39. text-align: center;
  40. font-size: 16px;
  41. background-color: #000000;
  42. }
  43. .sample *,
  44. .sample *:before,
  45. .sample *:after {
  46. -webkit-box-sizing: border-box;
  47. box-sizing: border-box;
  48. /* 当过了 0.55s 过渡效果 */
  49. -webkit-transition: all 0.55s ease;
  50. transition: all 0.55s ease;
  51. }
  52. /* 图片部分的样式 */
  53. .sample img {
  54. max-width: 100%;
  55. backface-visibility: hidden;
  56. vertical-align: top;
  57. }
  58. /* figcaption 用作文档中插图的图像,带有一个标题 */
  59. .sample figcaption {
  60. position: absolute;
  61. bottom: 25px;
  62. right: 25px;
  63. padding: 5px 10px 10px;
  64. }
  65. /* 绘制线条 */
  66. .sample figcaption:before,
  67. .sample figcaption:after {
  68. height: 2px;
  69. width: 400px;
  70. position: absolute;
  71. content: '';
  72. background-color: #ffffff;
  73. }
  74. /* 上面一条线 */
  75. .sample figcaption:before {
  76. top: 0;
  77. left: 0;
  78. -webkit-transform: translateX(100%);
  79. transform: translateX(100%);
  80. }
  81. /* 下面一条线 */
  82. .sample figcaption:after {
  83. bottom: 0;
  84. right: 0;
  85. -webkit-transform: translateX(-100%);
  86. transform: translateX(-100%);
  87. }
  88. /* 绘制线条 */
  89. .sample figcaption div:before,
  90. .sample figcaption div:after {
  91. width: 2px;
  92. height: 300px;
  93. position: absolute;
  94. content: '';
  95. background-color: #ffffff;
  96. }
  97. /* 左面一条线 */
  98. .sample figcaption div:before {
  99. top: 0;
  100. left: 0;
  101. -webkit-transform: translateY(100%);
  102. transform: translateY(100%);
  103. }
  104. /* 右面一条线 */
  105. .sample figcaption div:after {
  106. bottom: 0;
  107. right: 0;
  108. -webkit-transform: translateY(-100%);
  109. transform: translateY(-100%);
  110. }
  111. /* 文字部分 */
  112. .sample h2,
  113. .sample h4 {
  114. margin: 0;
  115. text-transform: uppercase;
  116. }
  117. .sample h2 {
  118. font-weight: 400;
  119. }
  120. .sample h4 {
  121. display: block;
  122. font-weight: 700;
  123. background-color: #ffffff;
  124. padding: 5px 10px;
  125. color: #000000;
  126. }
  127. .sample a {
  128. position: absolute;
  129. top: 0;
  130. bottom: 0;
  131. left: 0;
  132. right: 0;
  133. }
  134. /* 当鼠标放到图片时的效果, .hover 仅演示需要,可自行取消 */
  135. .sample:hover img,
  136. .sample.hover img {
  137. zoom: 1;
  138. filter: alpha(opacity=50);
  139. -webkit-opacity: 0.5;
  140. opacity: 0.5;
  141. }
  142. .sample:hover figcaption:before,
  143. .sample.hover figcaption:before,
  144. .sample:hover figcaption:after,
  145. .sample.hover figcaption:after,
  146. .sample:hover figcaption div:before,
  147. .sample.hover figcaption div:before,
  148. .sample:hover figcaption div:after,
  149. .sample.hover figcaption div:after {
  150. -webkit-transform: translate(0, 0);
  151. transform: translate(0, 0);
  152. }
  153. .sample:hover figcaption:before,
  154. .sample.hover figcaption:before,
  155. .sample:hover figcaption:after,
  156. .sample.hover figcaption:after {
  157. /* 过渡延时 0.15s */
  158. -webkit-transition-delay: 0.15s;
  159. transition-delay: 0.15s;
  160. }
  161. /* 背景仅演示作用 */

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

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

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

这里的代码不变

  1. import org.thymeleaf.TemplateEngine;
  2. import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
  3. import javax.servlet.ServletContext;
  4. import javax.servlet.ServletContextEvent;
  5. import javax.servlet.ServletContextListener;
  6. import javax.servlet.annotation.WebListener;
  7. @WebListener
  8. public class ThymeleafConfig implements ServletContextListener {
  9. @Override
  10. public void contextInitialized(ServletContextEvent servletContextEvent) {
  11. System.out.println("ServletContext 初始化完毕");
  12. ServletContext context = servletContextEvent.getServletContext();
  13. TemplateEngine engine = new TemplateEngine();
  14. ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(context);
  15. resolver.setPrefix("/WEB-INF/template/");
  16. resolver.setSuffix(".html");
  17. resolver.setCharacterEncoding("utf-8");
  18. engine.setTemplateResolver(resolver);
  19. context.setAttribute("engine",engine);
  20. }
  21. @Override
  22. public void contextDestroyed(ServletContextEvent servletContextEvent) {
  23. }
  24. }

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

创建一个 Image 类

  1. class Image {
  2. public String name;
  3. public String url;
  4. }

创建一个类,重写 doGet 方法

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

实现 loadImage 方法

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

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

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

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

注意一定要加上注解@MultipartConfig

  1. import javax.servlet.ServletException;
  2. import javax.servlet.annotation.MultipartConfig;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import javax.servlet.http.Part;
  8. import java.io.IOException;
  9. // 这个注解在上传文件的功能中是必要的
  10. @MultipartConfig
  11. @WebServlet("/upload")
  12. public class UploadServlet extends HttpServlet {
  13. @Override
  14. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  15. String path = getServletContext().getRealPath("/image");
  16. Part part = req.getPart("myImage");
  17. part.write(path + "/" + part.getSubmittedFileName());
  18. resp.sendRedirect("Image");
  19. }
  20. }

7. 注意事项

  1. 主要是得到文件夹,找到路径的步骤复杂点.重点掌握这几种方法的使用

  1. 前后端约定好的名称要对应.

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

8. 部署之后 运行截图

文件中已经存了两个图片,一运行就可以看到这些图片

点击图片还能放大

上传图片,上传两个图片

创作打卡挑战赛

赢取流量/现金/CSDN周边激励大奖

相关文章