文章目录
一. 案例: 表白墙 (使用模板引擎)
1. 首先创建 maven 项目
引入需要的依赖,创建必要的目录
2. 创建好模板文件
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>表白墙</title></head><body><formaction="confession"method="post"><divclass="parent"><divid="wall">表白墙</div><divid="remind">输入后点击提交,会将信息显示在表格中</div><divclass="one"><spanclass="two">谁:</span><inputtype="text"class="text"name="from"></div><divclass="one"><spanclass="two">对谁:</span><inputtype="text"class="text"name="to"></div><divclass="one"><spanclass="two">说什么:</span><inputtype="text"class="text"name="message"></div><divclass="one"><inputtype="submit"value="提 交"class="press"></div><divclass="elem"th:each="message : ${messages}"><spanth:text="${message.from}">wz</span>对<spanth:text="${message.to}">zw</span>说: <spanth: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
类
importcom.mysql.cj.jdbc.MysqlDataSource;importjavax.sql.DataSource;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassConnectionDB{privatestaticfinalString URL ="jdbc:mysql://127.0.0.1:3306/confessionWall2?characterEncoding=utf-8&useSSL=true&serverTimezone=UTC";privatestaticfinalString USERNAME ="root";privatestaticfinalString PASSWORD ="0000";privatestaticvolatileDataSource dataSource =null;publicstaticDataSourcegetDataSource(){if(dataSource ==null){synchronized(ConnectionDB.class){if(dataSource ==null){
dataSource =newMysqlDataSource();((MysqlDataSource) dataSource).setURL(URL);((MysqlDataSource) dataSource).setUser(USERNAME);((MysqlDataSource) dataSource).setPassword(PASSWORD);}}}return dataSource;}publicstaticConnectiongetConnection()throwsSQLException{returngetDataSource().getConnection();}publicstaticvoidclose(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
类
注意加上注解
importorg.thymeleaf.TemplateEngine;importorg.thymeleaf.templateresolver.ServletContextTemplateResolver;importjavax.servlet.ServletContext;importjavax.servlet.ServletContextEvent;importjavax.servlet.ServletContextListener;importjavax.servlet.annotation.WebListener;@WebListenerpublicclassThymeleafConfigimplementsServletContextListener{@OverridepublicvoidcontextInitialized(ServletContextEvent servletContextEvent){System.out.println("ServletContext 初始化完毕!");ServletContext context = servletContextEvent.getServletContext();TemplateEngine engine =newTemplateEngine();ServletContextTemplateResolver resolver =newServletContextTemplateResolver(context);
resolver.setPrefix("/WEB-INF/template/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("utf-8");
engine.setTemplateResolver(resolver);
context.setAttribute("engine",engine);}@OverridepublicvoidcontextDestroyed(ServletContextEvent servletContextEvent){}}
5. 编写 Servlet 代码
首先创建一个
Confession
类
classConfession{publicString from;publicStringto;publicString message;}
① 重写 doGet 方法
@OverrideprotectedvoiddoGet(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{
resp.setContentType("text/html;charset=utf-8");List<Confession> list =load();TemplateEngine engine =(TemplateEngine)getServletContext().getAttribute("engine");WebContext webContext =newWebContext(req,resp,getServletContext());
webContext.setVariable("messages",list);
engine.process("confessionwall",webContext, resp.getWriter());}
② 重写 doPost 方法
resp.setContentType("text/html;charset=utf-8");Confession confession =newConfession();
confession.from = req.getParameter("from");
confession.to= req.getParameter("to");
confession.message = req.getParameter("message");save(confession);
resp.sendRedirect("confession");
③ 实现 load 方法
privateList<Confession>load(){List<Confession> list =newArrayList<>();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 =newConfession();
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 方法
privatevoidsave(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. 注意事项
- 注意模板引擎
- 注意 乱码的情况,要添加
utf-8
- 用数据库的方法存数据,要先创建好数据库
createdatabase confessionWall2;use confessionWall2;createtable confession(`from`varchar(1024),`to`varchar(1024),`message`varchar(1024));
- 还有一些必要的注解也要加上.
7. 部署之后 运行截图
浏览器输入对应的URL
在数据库为空的时候界面如下
在输入几个数据之后 如下
此时的数据库中表的内容
重新部署再进入URL发现数据还是存在.
二. 案例: 在线相册 (使用模板引擎)
1. 首先创建 maven 项目
引入必要的依赖,已经必要的目录
2. 创建好模板文件
image.html
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>相册</title><linkrel="stylesheet"href="./style.css"></head><body><divclass="nav"><formaction="upload"method="POST"enctype="multipart/form-data"><inputtype="file"name="myImage"><inputtype="submit"value="上传图片"></form></div><divclass="parent"><!-- 第一组图片 --><figureclass="sample"th:each="image : ${images}"><imgth:src="${image.url}"alt="sample1"/><figcaption><div><h2th:text="${image.name}">Deconovo</h2></div></figcaption><ath:href="${image.url}"></a></figure></div></body></html>
style.css
/* 引入文字样式库 */@importurl(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;/* 当过了 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 用作文档中插图的图像,带有一个标题 */.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;}/* 当鼠标放到图片时的效果, .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{/* 过渡延时 0.15s */-webkit-transition-delay: 0.15s;transition-delay: 0.15s;}/* 背景仅演示作用 */
3. 这是通过访问文件夹里的图片的
在webapp下创建一个文件夹 image,里面存放图片.
通过
getServletContext().getRealPath("/image")
来获取绝对路径
4. 使用 监视器 来初始化 Thymeleaf
这里的代码不变
importorg.thymeleaf.TemplateEngine;importorg.thymeleaf.templateresolver.ServletContextTemplateResolver;importjavax.servlet.ServletContext;importjavax.servlet.ServletContextEvent;importjavax.servlet.ServletContextListener;importjavax.servlet.annotation.WebListener;@WebListenerpublicclassThymeleafConfigimplementsServletContextListener{@OverridepublicvoidcontextInitialized(ServletContextEvent servletContextEvent){System.out.println("ServletContext 初始化完毕");ServletContext context = servletContextEvent.getServletContext();TemplateEngine engine =newTemplateEngine();ServletContextTemplateResolver resolver =newServletContextTemplateResolver(context);
resolver.setPrefix("/WEB-INF/template/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("utf-8");
engine.setTemplateResolver(resolver);
context.setAttribute("engine",engine);}@OverridepublicvoidcontextDestroyed(ServletContextEvent servletContextEvent){}}
5. 编写加载页面的 Servlet代码
创建一个 Image 类
classImage{publicString name;publicString url;}
创建一个类,重写 doGet 方法
@WebServlet("/Image")publicclassOnlineImageServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{
resp.setContentType("text/html;charset=utf-8");// 1. 扫描指定路径 /webapp/image 路径List<Image> images =loadImage();// 2. 构造到模板页面TemplateEngine engine =(TemplateEngine)getServletContext().getAttribute("engine");WebContext webContext =newWebContext(req,resp,getServletContext());
webContext.setVariable("images",images);String html = engine.process("image",webContext);
resp.getWriter().write(html);}}
实现 loadImage 方法
注意使用 getRealPath 方法
以及注意使用 file.listFiles()方法
privateList<Image>loadImage(){List<Image> images =newArrayList<>();// 首先得到 /webapp/image 的绝对路径ServletContext context =this.getServletContext();// 这里是将 webapp下的目录转换成一个绝对路径String path = context.getRealPath("/image");// 根据路径 看里面有哪些图片.File file =newFile(path);File[] files = file.listFiles();for(File f:files){Image image =newImage();
image.name = f.getName();
image.url ="image/"+f.getName();
images.add(image);}return images;}
6. 编写提交图片的 Servlet 代码
① 创建一个类,重写 doPost 方法
注意一定要加上注解
@MultipartConfig
importjavax.servlet.ServletException;importjavax.servlet.annotation.MultipartConfig;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.http.Part;importjava.io.IOException;// 这个注解在上传文件的功能中是必要的@MultipartConfig@WebServlet("/upload")publicclassUploadServletextendsHttpServlet{@OverrideprotectedvoiddoPost(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{String path =getServletContext().getRealPath("/image");Part part = req.getPart("myImage");
part.write(path +"/"+ part.getSubmittedFileName());
resp.sendRedirect("Image");}}
7. 注意事项
- 主要是得到文件夹,找到路径的步骤复杂点.重点掌握这几种方法的使用
- 前后端约定好的名称要对应.
- 传文件需要加上注解,否则会报500的错误.
@MultipartConfig
8. 部署之后 运行截图
文件中已经存了两个图片,一运行就可以看到这些图片
点击图片还能放大
上传图片,上传两个图片
版权归原作者 独一无二的哈密瓜 所有, 如有侵权,请联系我们删除。