JavaWeb項(xiàng)目實(shí)戰(zhàn)之表白墻和在線相冊
一. 案例: 表白墻 (使用模板引擎)
1. 首先創(chuàng)建 maven 項(xiàng)目
引入需要的依賴,創(chuàng)建必要的目錄
2. 創(chuàng)建好模板文件
<!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">輸入后點(diǎn)擊提交,會(huì)將信息顯示在表格中</div> <div class="one"><span class="two">誰:</span><input type="text" class="text" name="from"></div> <div class="one"><span class="two">對(duì)誰:</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>對(duì)<span th:text="${message.to}">zw</span>說: <span th:text="${message.message}">wzz</span> </div> </div> </form> <style> /* 去除瀏覽器默認(rèn)樣式 */ * { margin: 0; padding: 0; } /* 設(shè)置總寬度 */ .parent { width: 400px; margin: 0 auto; } /* 設(shè)置表白墻樣式 */ #wall { font-size: 30px; font-weight: 700; text-align: center; margin: 5px; } /* 設(shè)置提示信息樣式 */ #remind{ font-size:13px; text-align: center; color:gray; margin: 5px; } /* 設(shè)置彈性布局 */ .one { display: flex; justify-content: center; align-items: center; height: 40px; } /* 設(shè)置文字內(nèi)容 */ .two { width: 100px; line-height: 40px; } /* 設(shè)置輸入框 */ .one .text{ width: 200px; height: 20px; padding-left: 3px; } /* 提交按鈕的設(shè)置 */ .one .press{ width: 304px; height: 40px; color:white; background-color: orange; border-radius: 5px; border: none; } /* 設(shè)置鼠標(biāo)點(diǎn)擊的時(shí)候改變顏色 */ .one .press:active{ background-color: red; } /* 提交之后內(nèi)容的設(shè)置 */ .elem { text-align: center; margin: 15px; } </style> </body> </html>
3. 使用數(shù)據(jù)庫存儲(chǔ)數(shù)據(jù).創(chuàng)建一個(gè)類用于數(shù)據(jù)庫連接
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. 使用 監(jiān)視器 來初始化 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; @WebListener public 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 代碼
首先創(chuàng)建一個(gè) 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");
③ 實(shí)現(xiàn) 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; }
④ 實(shí)現(xiàn) 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. 注意事項(xiàng)
注意模板引擎
注意 亂碼的情況,要添加utf-8
用數(shù)據(jù)庫的方法存數(shù)據(jù),要先創(chuàng)建好數(shù)據(jù)庫
create database confessionWall2; use confessionWall2; create table confession( `from` varchar(1024), `to` varchar(1024), `message` varchar(1024) );
還有一些必要的注解也要加上.
7. 部署之后 運(yùn)行截圖
瀏覽器輸入對(duì)應(yīng)的URL
在數(shù)據(jù)庫為空的時(shí)候界面如下
在輸入幾個(gè)數(shù)據(jù)之后 如下
此時(shí)的數(shù)據(jù)庫中表的內(nèi)容
重新部署再進(jìn)入U(xiǎn)RL發(fā)現(xiàn)數(shù)據(jù)還是存在.
二. 案例: 在線相冊 (使用模板引擎)
1. 首先創(chuàng)建 maven 項(xiàng)目
引入必要的依賴,已經(jīng)必要的目錄
2. 創(chuàng)建好模板文件
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 部分的整體樣式 */ .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; /* 當(dāng)過了 0.55s 過渡效果 */ -webkit-transition: all 0.55s ease; transition: all 0.55s ease; } /* 圖片部分的樣式 */ .sample img { max-width: 100%; backface-visibility: hidden; vertical-align: top; } /* figcaption 用作文檔中插圖的圖像,帶有一個(gè)標(biāo)題 */ .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; } /* 當(dāng)鼠標(biāo)放到圖片時(shí)的效果, .hover 僅演示需要,可自行取消 */ .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 { /* 過渡延時(shí) 0.15s */ -webkit-transition-delay: 0.15s; transition-delay: 0.15s; } /* 背景僅演示作用 */
3. 這是通過訪問文件夾里的圖片的
在webapp下創(chuàng)建一個(gè)文件夾 image,里面存放圖片.
通過 getServletContext().getRealPath("/image")
來獲取絕對(duì)路徑
4. 使用 監(jiān)視器 來初始化 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; @WebListener public 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代碼
創(chuàng)建一個(gè) Image 類
class Image { public String name; public String url; }
創(chuàng)建一個(gè)類,重寫 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. 構(gòu)造到模板頁面 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); } }
實(shí)現(xiàn) loadImage 方法
注意使用 getRealPath 方法
以及注意使用 file.listFiles()方法
private List<Image> loadImage() { List<Image> images = new ArrayList<>(); // 首先得到 /webapp/image 的絕對(duì)路徑 ServletContext context = this.getServletContext(); // 這里是將 webapp下的目錄轉(zhuǎn)換成一個(gè)絕對(duì)路徑 String path = context.getRealPath("/image"); // 根據(jù)路徑 看里面有哪些圖片. 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 代碼
① 創(chuàng)建一個(gè)類,重寫 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; // 這個(gè)注解在上傳文件的功能中是必要的 @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. 注意事項(xiàng)
主要是得到文件夾,找到路徑的步驟復(fù)雜點(diǎn).重點(diǎn)掌握這幾種方法的使用
前后端約定好的名稱要對(duì)應(yīng).
傳文件需要加上注解,否則會(huì)報(bào)500的錯(cuò)誤.@MultipartConfig
8. 部署之后 運(yùn)行截圖
文件中已經(jīng)存了兩個(gè)圖片,一運(yùn)行就可以看到這些圖片
點(diǎn)擊圖片還能放大
上傳圖片,上傳兩個(gè)圖片
總結(jié)
到此這篇關(guān)于JavaWeb項(xiàng)目實(shí)戰(zhàn)之表白墻和在線相冊的文章就介紹到這了,更多相關(guān)JavaWeb表白墻和在線相冊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring?boot常見get?、post請(qǐng)求參數(shù)處理、參數(shù)注解校驗(yàn)、參數(shù)自定義注解校驗(yàn)問題解析
這篇文章主要介紹了spring?boot常見get?、post請(qǐng)求參數(shù)處理、參數(shù)注解校驗(yàn)、參數(shù)自定義注解校驗(yàn),本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09java實(shí)現(xiàn)文本框和文本區(qū)的輸入輸出
這篇文章主要介紹了java實(shí)現(xiàn)文本框和文本區(qū)的輸入輸出的方法和具體示例,有需要的小伙伴可以參考下。2015-06-06Java 實(shí)現(xiàn)簡單Socket 通信的示例
這篇文章主要介紹了Java 實(shí)現(xiàn)簡單Socket 通信的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-03-03教你創(chuàng)建springcloud微服務(wù)的基礎(chǔ)子服務(wù)的超詳細(xì)過程
這篇文章主要介紹了創(chuàng)建springcloud微服務(wù)的基礎(chǔ)子服務(wù),主要是創(chuàng)建兩個(gè)springboot服務(wù),在教程中增加springcloud相關(guān)組件,本文分步驟給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04Java IO文件過濾器對(duì)命令設(shè)計(jì)模式的使用
java io流里面使用到了很多的設(shè)計(jì)模式,最典型的就是裝飾模式,還有命令模式,下面分兩部分來講Java IO文件過濾器對(duì)命令設(shè)計(jì)模式的使用,一起看看吧2017-06-06在springboot中使用注解將值注入?yún)?shù)的操作
這篇文章主要介紹了在springboot中使用注解將值注入?yún)?shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04java實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)發(fā)送郵箱驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08