1.读取
实现思路:使用byte[]从数据库获取二进制图片数据,然后转换为图片保存到路径,通过路径读取图片。
数据库设计
这里不建议把图片直接保存在数据库(我也是做完才知道…),建议存放路径到数据库,这样可以减少了数据访问上的压力。
代码实现
/*
* 查询方法
*/
public List<BookManagePo> findAll() {
List<BookManagePo> list = new ArrayList<BookManagePo>();
try {
con = DButil.getConnection();
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
//通过反射把数据库数据保存到BookManagePo中
list=JdbcHelper.getResult(rs, BookManagePo.class);
String path="";
for (int i = 0; i < list.size(); i++) {
path="C:\\Workspaces\\BMS\\BMS\\WebRoot\\Content\\bookImg\\"+list.get(i).getBook_id()+".jpg";
list.get(i).setImg_path(ByteToImg.byteimage(list.get(i).getBook_img(), path));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DButil.Close(con, ps, rs);
}
return list;
}
//反射方法
public static <T> List<T> getResult(ResultSet rs, Class<T> obj) {
try {
List<T> list = new ArrayList<T>();
// ResultSetMetaData 有关 ResultSet 中列的名称和类型的信息。
ResultSetMetaData metaData = rs.getMetaData();
Field[] fields = obj.getDeclaredFields();
// 获取总的列数
int count = metaData.getColumnCount();
// 遍历ResultSet
while (rs.next()) {
// ---创建对象实例
T instance = obj.newInstance();
for (int i = 1; i <= count; i++) {
// ---获取列名
String name = metaData.getColumnName(i);
for(Field field:fields){
if(name.equals(field.getName())){
// 改变列名格式成 java 命名格式 主要是针对 _ 分割的情况 如user_id
//name = toJavaField(name);
// ---获取类型
Class<?> type = obj.getDeclaredField(name).getType();
// ---获取setter方法
// 首字母大写
String replace = name.substring(0, 1).toUpperCase()
+ name.substring(1);
Method setMethod = obj.getMethod("set" + replace, type);
// ---判断读取数据的类型
if (type.isAssignableFrom(String.class)) {
//Thread.sleep(1000);
System.out.println(name);
//String str = name.substring(1);
setMethod.invoke(instance, rs.getString(i).trim());
} else if (type.isAssignableFrom(int.class)
|| type.isAssignableFrom(Integer.class)) {
setMethod.invoke(instance, rs.getInt(i));
} else if (type.isAssignableFrom(Boolean.class)
|| type.isAssignableFrom(boolean.class)) {
setMethod.invoke(instance, rs.getBoolean(i));
} else if (type.isAssignableFrom(Date.class)) {
setMethod.invoke(instance, rs.getTimestamp(i));
}
else if (type.isAssignableFrom(Double.class)||type.isAssignableFrom(double.class)) {
setMethod.invoke(instance, rs.getDouble(i));
}else if(type.isAssignableFrom(byte[].class)){
setMethod.invoke(instance, rs.getBytes(i));
}
}
}
}
list.add(instance);
}
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
/*
* 二进制转图片保存到路径
*/
public static String byteimage(byte[] data, String path) {
if (data.length < 3 || path.equals(""))
return "参数异常!";
try {
FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
imageOutput.write(data, 0, data.length);
imageOutput.close();
return path;
}
catch (Exception ex) {
ex.printStackTrace();
return ex.toString();
}
}
JSP页面
2.保存
JSP页面
js代码
$("#file").change(function () {
document.getElementById("IimgPicture").style.display = "block";
});
//FileReader接口提供了一个异步的API,通过这个API可以从浏览器中异步访问文件系统中的数据。因此,FileReader接口可以读取文件中的数据,并将读取的数据放入到内存中去
//选择照片:用FileReader对象来读取本地数据,并且将数据结果赋值给image的src、
//图片文件 正则表达式过滤
var imgReaderI = new FileReader();//FileReader()接口:用于读取文件
//图片文件: 正则表达式过滤(此表达式是用来判断上传的文件是否是一张图片)
regexImageFilter = /^(?:image\/bmp|image\/png|image\/jpeg|image\/jpg)$/i;
//调用FileReader接口的onload方法,回调函数得到的evt是图片的URL链接
imgReaderI.onload = function (evt) {
//将数据结果赋值给image的src
$("#IimgPicture").attr('src', evt.target.result);
};
//获取“选择文件”的按钮,调用改变事件
$("#file").change(function () {
//获取通过“选择文件”的按钮上传的文件
//prop添加属性名称(跟attr属性一样是给标签添加属性,但是它们是有区别的),加载image标签中
var imgfFile = $("#file").prop('files')[0];
//调用正则表达式过滤图片
if (!regexImageFilter.test(imgfFile.type)) {
layer.msg('选择的不是一个有效的图片文件', { icon: 0 });
} //readAsDataURL()方法可以获取API异步读取的文件数据,另存为数据URL;将该URL绑定到img标签的src属性上,就可以实现图片的上传预览效果了。
imgReaderI.readAsDataURL(imgfFile);
});
Servlet代码
/*
* 书籍新增
*/
private void addBook(HttpServletRequest request,
HttpServletResponse response) {
// TODO Auto-generated method stub
String bookname = "";
String bookprice = "";
String bookauthor = "";
String booksynopsis = "";
int mintype = 0;
List<FileItem> Files = new ArrayList<FileItem>();//存取上传文件
DiskFileItemFactory fu =new DiskFileItemFactory ();//创建一个解析器工厂
//得到解析器,处理上传的文件数据,并将表单中每个输入项封装成一个FileItem 对象中
ServletFileUpload upload = new ServletFileUpload(fu);
upload.setHeaderEncoding("utf-8");
try {
//存取表单所有信息
PrintWriter writer = response.getWriter();
List<FileItem> list = upload.parseRequest(request);//取得表单的数据内容
//此层增强for循环遍历表单中有多少个上传文件将文件存到list中
for(FileItem items:list){
if(items.isFormField()){//判断是否不是文件
if(items.getFieldName().equals("bookname")){
bookname=new String(items.getString().getBytes("ISO-8859-1"),"utf-8");
//System.out.println(name);
}else if(items.getFieldName().equals("bookprice")){
bookprice=new String(items.getString().getBytes("ISO-8859-1"),"utf-8");
}else if(items.getFieldName().equals("bookauthor")){
bookauthor=new String(items.getString().getBytes("ISO-8859-1"),"utf-8");
}else if(items.getFieldName().equals("booksynopsis")){
booksynopsis=new String(items.getString().getBytes("ISO-8859-1"),"utf-8");
}else if(items.getFieldName().equals("mintype")){
mintype=new Integer(items.getString());
}
//System.out.println(items.getFieldName());
}else{
Files.add(items);
}
}
//sql插入语句
if(Files.size()>0){
for(int i=0;i<Files.size();i++){
FileItem item = Files.get(i);//从集合取出文件
InputStream file = item.getInputStream();//将文件转为输入流
// read(byte[])方法,返回读入缓冲区的总字节数
byte[] buffer = new byte[file.available()];//将字节数组直接存进去数据库就可以
file.read(buffer);
Boolean isTF=bookManageService.addBook(bookname,bookprice,bookauthor,booksynopsis,mintype,buffer);
if (isTF) {
writer.write("新增成功!");
}else{
writer.write("新增失败!");
}
}
}else{
writer.write("请上传图片!");
}
} catch (FileUploadException e2) {
e2.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//新增方法
public boolean addBook(String bookname, String bookprice,
String bookauthor, String booksynopsis, int mintype, byte[] buffer) {
// TODO Auto-generated method stub
try{
con = DButil.getConnection();
ps = con.prepareStatement(addBook);
ps.setString(1, bookname);
ps.setString(2, bookprice);
ps.setString(3, bookauthor);
ps.setString(4, booksynopsis);
ps.setInt(5, mintype);
ps.setBytes(6, buffer);
if(ps.executeUpdate()>0)
return true;
else
return false;
}catch(SQLException ex){
ex.printStackTrace();
return false;
}finally{
DButil.Close(con, ps, rs);
}
}