Java Web 图片管理与分享系统(Struts2+Hibernate+JSP实现)
2017-05-21 17:34
1111 查看
本示例是使用JavaWeb技术实现一个简单的图片管理与分享系统,其中主要功能如下:
用户分类浏览系统中的图片缩略图用户查看单张图片的详细信息,图片下载
用户查看一个分类内的所有图片缩略图
用户使用关键字进行模糊搜索
管理员登录
管理员拥有普通用户的所有功能,同时能够实现图片的删除
使用的主要技术有:
JavaEE、JSP、Struts2、Hibernate、JavaBean
本项目开发环境为:
Intellij IDEA 2016.3
Tomcat 8
JDK 1.8
MySQL 5.5
由于本人水平有限,该工程也只是我一边学习一边开发的一个用于课程作业的项目,所以其中还有很多不完善的地方,难免在某些情况下会有些bug,希望大家能够谅解。其实这个作业做了也过了快一个月了,很久没有更新博客了,所以今天这里记录下来,希望能够给其他同学一个参考和帮助,如果有什么建议或者问题也欢迎在博客下留言~
完整工程下载地址(包含网页截图和数据库建表sql文件):
http://download.csdn.net/detail/qq_24369113/9848301
简单的界面展示:
1.主页界面index.jsp:
2.图片详情页面item_preview.jsp:
3. 图片分类浏览页面AllcartoonPic.jsp/SearchResult.jsp:
4.图片上传界面contact.jsp:
为了方便大家建立数据库,这里也放上数据库的数据字典截图:
核心代码介绍:
对于主界面显示的index.jsp 主要就是调用Javabean(QueryAllPhoto)来从后台查询数据,然后返回一个ArrayList(person_pic_list),列表里面的每一个元素强制转换成一个PhotoInfoEntity对象之后,就可以取出每张图片的各种信息,主要代码片段如下:
其中index.jsp页面会有三个这种div,每一个div里显示八张该类别的图片的缩略图。其他的div里只是String category更换成相应的值就好了。
<div class="row"> <div class="col-xs-12 col-md-12"> <div class="item_container"> <% String category = "人物图片"; QueryAllPhoto query = new QueryAllPhoto(); ArrayList person_pic_list = query.QueryByExt(category); %> <% for (int i = 0; i < 8 && i < person_pic_list.size(); i++) { PhotoInfoEntity tem = (PhotoInfoEntity) person_pic_list.get(i); %> <!--一张图片的信息===============================================================================================================--> <div class="item"> <a href="item_preview.jsp?id=<%=tem.getId()%>&dir=<%=tem.getDir()%>&ext=<%=tem.getExt()%>&realName=<%=tem.getRelName()%>&ip=<%=tem.getIp()%>&dt=<%=tem.getDt()%>&info=<%=tem.getInfo()%>" class="thumbnail"> <img src="<%=tem.getDir()%>" alt="377 blue tech"> <p><%=tem.getRelName()%> </p> </a> </div> <% } %> </div> </div> </div>
每个jsp页面的查询功能是由下面这一小段代码实现:
通过post 方法将keyword信息提交到SearchResult.jsp页面。
<form action="SearchResult.jsp" method="post" class="navbar-form navbar-right" role="search"> <div class="form-group"> <input type="text" class="form-control" name="keyword" id="keyword" placeholder="图片查询"> </div> <button type="submit" class="btn btn-default">查询</button> </form>
在SearchResult.jsp页面,使用String keyword = request.getParameter("keyword");得到需要查询的图片关键字信息,然后同样调用后台的JavaBean实现查询,并将结果返回到一个ArrayList中。然后和index.jsp一样将一张张的图片显示出来。
核心代码片段如下:
<div class="row"> <div class="col-xs-12 col-md-12"> <div class="item_container"> <% String keyword = request.getParameter("keyword"); QueryAllPhoto query = new QueryAllPhoto(); ArrayList pic_list = query.QueryByKeyword(keyword); %> <% if (pic_list.size() == 0) { %> <div class="item"> <p><b>查询不到相关的图片,请更换关键字再次尝试。</b></p> </div> <% } else { for (int i = 0; i < pic_list.size(); i++) { PhotoInfoEntity tem = (PhotoInfoEntity) pic_list.get(i); %> <!-- 一张图片的信息======================================--> <div class="item"> <a href="item_preview.jsp?id=<%=tem.getId()%>&dir=<%=tem.getDir()%>&ext=<%=tem.getExt()%>&realName=<%=tem.getRelName()%>&ip=<%=tem.getIp()%>&dt=<%=tem.getDt()%>&info=<%=tem.getInfo()%>" class="thumbnail"> <img src="<%=tem.getDir()%>" alt="377 blue tech"> <p><%=tem.getRelName()%> </p> </a> </div> <% } } %> </div> </div> </div>
在index.jsp界面点击一张图片的缩略图会自动跳转到该图片的详情页,实现思路是点击图片缩略图之后会自动跳转到item_preview.jsp页面,由于在URL中存储了图片的相关信息,所以在item_preview.jsp页面直接使用request.getparameter()方法就能够得到该图片的各种详细信息。然后在直接显示出来就行。
<a href="item_preview.jsp?id=<%=tem.getId()%>&dir=<%=tem.getDir()%>&ext=<%=tem.getExt()%>&realName=<%=tem.getRelName()%>&ip=<%=tem.getIp()%>&dt=<%=tem.getDt()%>&info=<%=tem.getInfo()%>"
实际上,我的这种实现方式并不科学,我这种相当于在index.jsp页面就已经把一张图片的各种信息都查询出来了,然后只是没有显示出来而已,然后在图片详情页再直接显示出来,这样的话其实在图片数量较多或图片较大的情况下,index.jsp页面的加载将会非常的缓慢。
较科学的实现方式是,在index.jsp页面只查询图片的标签信息、图片编号、图片的存储路径,然后在item_preview.jsp页面根据图片的编号信息再去查询一次数据库得到图片的完整详情。
前台的代码还有一个需要说明的地方就是管理员的登录,使用的是Struts2,框架来实现登录信息的处理的,主要代码片度如下:
form表单中使用post方式将表单信息提交到CheckLogin.action这个action来处理。Struts2框架会捕捉到这个请求并实例化相应的action类来进行相应的处理。
<form method="post" action="CheckLogin.action"> <div class="panel"> <div class="panel-head"><strong>管理员登录</strong></div> <div class="panel-body" style="padding:30px;"> <div class="form-group"> <div class="field field-icon-right"> <input type="text" class="input" name="admin" placeholder="登录账号" /> <span class="icon icon-user"></span> </div> </div> <div class="form-group"> <div class="field field-icon-right"> <input type="password" class="input" name="password" placeholder="登录密码" /> <span class="icon icon-key"></span> </div> </div> </div> <div class="panel-foot text-center"> <button class="button button-block bg-main text-big">立即登录</button> </div> </div> </form>
上传图片的contact.jsp也是使用Struts2框架来捕获上传的图片信息和请求,主要代码如下:
表单通过post方式将表单信息提交到UploadPic这个action进行处理。
<form role="form" enctype="multipart/form-data" method="post" action="UploadPic"> <div class="row"> <div class="col-md-5"> <div class="form-group"> <input name="pic_name" type="text" class="form-control" id="pic_name" placeholder="图片名称"> </div> <div class="form-group"> <select name="pic_ext" type="text" class="form-control" id="pic_ext" placeholder="图片类型"> <option>卡通图片</option> <option>风景图片</option> <option>人物图片</option> </select> </div> <div class="form-group"> <input type="file" name="pic_data" id="pic_data" class="form-control"/> </div> </div> <div class="col-md-7"> <div class="form-group"> <textarea name="pic_info" rows="6" class="form-control" id="pic_info" placeholder="图片描述信息..."></textarea><br> <button type="submit" class="btn btn-primary">确认上传</button> </div> </div> </div> </form>
下面介绍Struts2的配置文件:
以第一个action为例,name属性是表示这个action的名称为UploadPic(也就是jsp中form表单里填写的那个),
class属性是指定执行该请求的实体类是cn.hncu.Action包下的UploadAction.java这个类,
method属性表示调用UploadAction.java这个类中的ajaxGetImage()这个方法来具体处理,
result标签表示如果ajaxGetImage()的返回值是字符串“Successful”那么就跳转到index.jsp,
如果ajaxGetImage()的返回值是字符串“failed”那么跳转到contact.jsp。
下面的两个action也是以此类推。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="struts2" namespace="/" extends="struts-default"> <action name="UploadPic" class="cn.hncu.Action.UploadAction" method="ajaxGetImage"> <result name="successful">index.jsp</result> <result name="failed">contact.jsp</result> </action> <action name="DeletePic" class="cn.hncu.Action.DeleteAction" method="DeleteImage"> <result name="successful">index.jsp</result> <result name="failed">item_preview.jsp</result> </action> <action name="CheckLogin" class="cn.hncu.Action.CheckLoginAction" method="check"> <result name="successful">index.jsp</result> <result name="failed">AdminLogin.jsp</result> </action> </package> </struts>
接下来是要实现UPloadAction类和其中的方法:
Struts2框架会自动实例化一个UploadAction对象,然后将jsp表单中的属性使用setter和getter方法封装到这个对象的同名属性中,然后自动调用配置文件中指定的ajaxGetImage()方法。
package cn.hncu.Action; import cn.hncu.Dao.PhotoInfoEntity; import org.apache.struts2.ServletActionContext; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by 32706 on 2017/4/19. */ public class UploadAction { private File pic_data;//Ajax获取图片文件,与控件type=File中的name属性一样 private String pic_name;//Ajax获取图片文件名称,相应的name属性名称+FileName private String pic_ext;//图片类别 private String pic_info;//图片描述信息 /** * -----------相应的get和set方法---------------- **/ public File getPic_data() { return pic_data; } public void setPic_data(File pic_data) { this.pic_data = pic_data; } public String getPic_name() { return pic_name; } public void setPic_name(String pic_name) { this.pic_name = pic_name; } public String getPic_ext() { return pic_ext; } public void setPic_ext(String pic_ext) { this.pic_ext = pic_ext; } public String getPic_info() { return pic_info; } public void setPic_info(String pic_info) { this.pic_info = pic_info; } /** * 通过Ajax获取图片信息 * * @return * @throws IOException */ public String ajaxGetImage() throws Exception { HttpServletResponse response = ServletActionContext.getResponse(); response.setContentType("text/plain"); response.setCharacterEncoding("utf-8"); if (pic_data != null) { String fileName = pic_data.getName(); String savePath = ServletActionContext.getServletContext().getRealPath("/"); String finalPath = save_pic_on_disk(pic_data, savePath, fileName); if (finalPath != null)//将图片存储到本地文件 { if (upload_info_to_database(finalPath, pic_ext, pic_info, "administrator", pic_name))//调用hibernate将数据插入数据库 { response.getWriter().print("图片上传成功!");//把相应的地址放到前台解析,通过#符号分割 return "successful"; } else { System.out.println("调用hibernate持久化过程出错"); response.getWriter().print("图片上传失败!====调用hibernate持久化过程出错"); return "failed"; } } else { response.getWriter().print("图片上传失败!====保存到本地失败"); return "failed"; } } else { System.out.println("图片数据为空====================="); response.getWriter().print("图片上传失败!"); return "failed"; } } private boolean upload_info_to_database(String savePath, String pic_ext, String info, String ip, String pic_name) { try { java.util.Date date = new java.util.Date(); DateFormat format = new SimpleDateFormat("yyyy-MM-dd/HH:mm:ss"); String time = format.format(date);//得到完成订单的时间 DateFormat format1 = new SimpleDateFormat("yyyyMMddHHmmss"); String pic_id = format1.format(date) + (int) (Math.random() * 1000); Configuration conf = new Configuration().configure(); SessionFactory sf = conf.buildSessionFactory(); //Session session = sf.openSession(); Session session=sf.getCurrentSession(); PhotoInfoEntity photo = new PhotoInfoEntity(); photo.setDir(savePath); photo.setDt(time); photo.setExt(pic_ext); photo.setId(pic_id); photo.setInfo(info); photo.setIp(ip); photo.setRelName(pic_name); Transaction tran = session.beginTransaction(); session.save(photo); tran.commit(); session.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } private String save_pic_on_disk(File data, String savePath, String fileName) { String rt = ""; java.util.Date date = new java.util.Date(); DateFormat format = new SimpleDateFormat("yyyyMMdd"); String time = format.format(date);//得到完成订单的时间 System.out.println(savePath); String dir_url = "uploadImage/" + time + "/"; String realFileName=new Date().getTime()+fileName+".jpg"; String realPath=savePath+dir_url+realFileName; System.out.println("最终保存的文件路径为======" + realPath); try { File file = new File(savePath + dir_url);//每天的图片放在一个文件夹里 //如果文件夹不存在则创建 if (!file.exists() && !file.isDirectory()) { System.out.println(dir_url + "文件夹不存在,新建一个"); file.mkdir(); } FileOutputStream out=new FileOutputStream(realPath); FileInputStream in=new FileInputStream(data); byte[]buffer=new byte[1024]; int len=0; while((len=in.read(buffer))!=-1){ out.write(buffer,0,len); } out.flush(); out.close(); in.close(); return dir_url+realFileName; } catch (Exception e) { e.printStackTrace(); System.out.println("保存文件到文件中出错=================Database.save_picture_in_file"); return null; } } public static void main(String arg[]) { } }
另外两个Action的实现是类似的,这里限于版面就不在赘述了,大家可以下载完整的工程文件查看。(博客底部和顶部有下载链接)
介绍到这里还有一个前台使用的JavaBean没有介绍到,这个就是QueryAllphoto.java:
其中有两个方法,一个是QueryByExt()方法,表示根据图片的类别来查询,在图片分类浏览和index.jsp页面会使用到。
第二个方法是QueryByKeyword(),是使用图片标签的关键字来进行查询。
package cn.hncu.Dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.query.Query; import java.util.ArrayList; import java.util.List; public class QueryAllPhoto { public ArrayList QueryByExt(String category) { ArrayList rt=new ArrayList(); Configuration configuration=new Configuration().configure(); SessionFactory sessionFactory=configuration.buildSessionFactory(); Session session=sessionFactory.openSession(); String hql="from PhotoInfoEntity where ext='"+category+"'"; System.out.println(hql+"========================================================================"); Query query=session.createQuery(hql); List list=query.list(); for(int i=0;i<list.size();i++) { PhotoInfoEntity tem=(PhotoInfoEntity)list.get(i); rt.add(tem); } System.out.println(rt.size()+"大小========================================================================"); return rt; } public ArrayList QueryByKeyword(String keyword) { ArrayList rt=new ArrayList(); Configuration configuration=new Configuration().configure(); SessionFactory sessionFactory=configuration.buildSessionFactory(); Session session=sessionFactory.openSession(); String hql="from PhotoInfoEntity where relName like '%"+keyword+"%'"; System.out.println(hql+"========================================================================"); Query query=session.createQuery(hql); List list=query.list(); for(int i=0;i<list.size();i++) { PhotoInfoEntity tem=(PhotoInfoEntity)list.get(i); rt.add(tem); } System.out.println(rt.size()+"大小========================================================================"); return rt; } public static void main(String arg[]) { QueryAllPhoto q=new QueryAllPhoto(); ArrayList result=q.QueryByExt("风景图片"); System.out.println(result.size()); } }
在QueryAllPhoto.java中我们调用了Hibernate框架来实现数据的访问和查询等操作,下面就来介绍Hibernate的配置文件hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?> <!--表明解析本XML文件的DTD文档位置,DTD是Document Type Definition 的缩写,即文档类型的定义,XML解析器使用DTD文档来检查XML文件的合法性。hibernate.sourceforge.net/hibernate-configuration-3.0dtd可以在Hibernate3.1.3软件包中的src\org\hibernate目录中找到此文件--> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!--声明Hibernate配置文件的开始--> <hibernate-configuration> <!--表明以下的配置是针对session-factory配置的,SessionFactory是Hibernate中的一个类,这个类主要负责保存HIbernate的配置信息,以及对Session的操作--> <session-factory> <!--配置数据库的驱动程序,Hibernate在连接数据库时,需要用到数据库的驱动程序--> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <!--设置数据库的连接url:jdbc:mysql://localhost/hibernate,其中localhost表示mysql服务器名称,此处为本机, hibernate是数据库名--> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/photo</property> <!--连接数据库是用户名--> <property name="connection.username">root</property> <!--连接数据库是密码--> <property name="connection.password">root</property> <!--数据库连接池的大小--> <property name="hibernate.connection.pool.size">20</property> <!--是否在后台显示Hibernate用到的SQL语句,开发时设置为true,便于差错,程序运行时可以在Eclipse的控制台显示Hibernate的执行Sql语句。项目部署后可以设置为false,提高运行效率--> <property name="hibernate.show_sql">true </property> <!--jdbc.fetch_size是指Hibernate每次从数据库中取出并放到JDBC的Statement中的记录条数。Fetch Size设的越大,读数据库的次数越少,速度越快,Fetch Size越小,读数据库的次数越多,速度越慢--> <property name="jdbc.fetch_size">50 </property> <!--jdbc.batch_size是指Hibernate批量插入,删除和更新时每次操作的记录数。Batch Size越大,批量操作的向数据库发送Sql的次数越少,速度就越快,同样耗用内存就越大--> <property name="jdbc.batch_size">23 </property> <!--jdbc.use_scrollable_resultset是否允许Hibernate用JDBC的可滚动的结果集。对分页的结果集。对分页时的设置非常有帮助--> <property name="jdbc.use_scrollable_resultset">false </property> <!--connection.useUnicode连接数据库时是否使用Unicode编码--> <property name="Connection.useUnicode">true </property> <!--connection.characterEncoding连接数据库时数据的传输字符集编码方式,最好设置为gbk,用gb2312有的字符不全--> <property name="connection.characterEncoding">utf-8</property> <!--hibernate.dialect 只是Hibernate使用的数据库方言,就是要用Hibernate连接那种类型的数据库服务器。--> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect </property> <mapping resource="cn/hncu/Dao/PhotoInfoEntity.hbm.xml"/> <mapping class="cn.hncu.Dao.PhotoInfoEntity"/> <mapping class="cn.hncu.Dao.AdminEntity"/> <mapping resource="cn/hncu/Dao/AdminEntity.hbm.xml"/> </session-factory> </hibernate-configuration>
为了使Hibernate能够将数据库表和java对象联系起来,我们还需要两个持久化对象类:AdminEntity.java 以及PhotoInfoEntity.java
这两个类在intellij中是可以自动生成的,具体方法可以查看博文:http://blog.csdn.net/u014520745/article/details/51408049
在eclipse等 IDE中的生成方式请自行百度。
这里就简单介绍下AdminEntity.java:
该类中的每一个属性对应数据库表中的一个属性,然后每个属性会有一个setter和getter方法。
PhotoInfoEntity.java也是类似只是属性会多一些。
package cn.hncu.Dao; import javax.persistence.*; /** * Created by 32706 on 2017/4/20. */ @Entity @Table(name = "admin", schema = "photo", catalog = "") public class AdminEntity { private String adminName; private String password; @Id @Column(name = "admin_name") public String getAdminName() { return adminName; } public void setAdminName(String adminName) { this.adminName = adminName; } @Basic @Column(name = "password") public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AdminEntity that = (AdminEntity) o; if (adminName != null ? !adminName.equals(that.adminName) : that.adminName != null) return false; if (password != null ? !password.equals(that.password) : that.password != null) return false; return true; } @Override public int hashCode() { int result = adminName != null ? adminName.hashCode() : 0; result = 31 * result + (password != null ? password.hashCode() : 0); return result; } }
至此整个工程的一些主要核心代码就已经介绍完了,如果需要工程源文件请访问:
http://download.csdn.net/detail/qq_24369113/9848301
如有错误和纰漏请多多包含,欢迎在下面留言。
相关文章推荐
- [java源码] Java Web 文章管理系统(Jsp+Ajax+JDBC+MySql实现)
- Java Web 文章管理系统(Jsp+Ajax+JDBC+MySql实现)
- CMS内容管理系统开发- Java Web开发及发布实例(2)—使用JSP实现动态数据交互
- JAVA_WEB项目(结合Servlet+jsp+ckEditor编辑器+jquery easyui技术)实现新闻发布管理系统第二篇:登陆和注销功能实现
- JAVA_WEB项目(结合Servlet+jsp+ckEditor编辑器+jquery easyui技术)实现新闻发布管理系统第四篇:前台首页,新闻分类(体育新闻,科技新闻等),新闻列表分页的实现
- JAVA_WEB项目(结合Servlet+jsp+ckEditor编辑器+jquery easyui技术)实现新闻发布管理系统第三篇:新闻发布,新闻修改,新闻删除功能的实现
- jsp struts实现的Java web信息供求系统项目源码
- JAVA_WEB项目(结合Servlet+jsp+ckEditor编辑器+jquery easyui技术)实现新闻发布管理系统第一篇:前期环境准备
- [java源码] Java Web 文章管理系统(Jsp+Ajax+JDBC+MySql实现)
- Java Web 文章管理系统(Jsp+Ajax+JDBC+MySql实现)
- Java Web 文章管理系统(Jsp+Ajax+JDBC+MySql实现)
- java web 项目 图书管理系统的设计与实现
- java web 权限管理系统设计与实现
- 学生信息管理系统【JavaWeb】SSH+Mysql+Jsp
- 基于james3.0 的邮件系统(struts2.3.2 +spring3.0.1+jpa(hibernate3.6.5)实现)b/s模式--java邮件系统 .
- JSP+Servlet培训班作业管理系统[23] -番外篇之Java Web日志
- 基于james3.0 的邮件系统(struts2.3.2 +spring3.0.1+jpa(hibernate3.6.5)实现)b/s模式--java邮件系统
- 基于james3.0 的邮件系统(struts2.3.2 +spring3.0.1+jpa(hibernate3.6.5)实现)b/s模式--java邮件系统
- newxy+struts实现零java代码或极少java代码开发以数据为中心的web运用系统 作者:胡立新
- java web 项目 图书管理系统的设计与实现