当我们在jsp页面想要上传一个图片到本地并在另一个页面回显时,需要怎样处理?需要注意什么问题?
一:下载好需要的jar包
1.comons-fileupload.jar
2.commons-io.jar
二.编写jsp页面
注意
1.当form表单要向servlet传的数据类型为图片时,需要首先在表单中加上enctype=“multipart/form-data”,用于表单里有图片上传的情况。
2.表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作. enctype="multipart/form-data"是上传二进制数据; form里面的input的值以2进制的方式传过去。
3.这时如果表单中除了文件,还有其他类型的内容时,Servlet中用request是获取不到值的。
三.Servlet获取图片并上传到本地指定文件夹
代码(1):
@WebServlet(name="upload",urlPatterns = "/upload")
public class UploadFileServlet extends HttpServlet {
BlogDaoImpl bd = new BlogDaoImpl();
SmartUpload su = new SmartUpload();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DiskFileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(factory);
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;utf-8");
String user = null;
String path = null;
//设置缓冲区大小与临时文件目录
factory.setSizeThreshold(1024*1024*10);
File uploadTemp=new File("e:\\uploadTemp");
uploadTemp.mkdirs();
factory.setRepository(uploadTemp);
//设置单个文件大小限制
upload.setFileSizeMax(1024*1024*10);
//设置所有文件总和大小限制
upload.setSizeMax(1024*1024*30);
try {
List list=upload.parseRequest(request);
System.out.println(list);
for (FileItem fileItem:list){
if (!fileItem.isFormField()&&fileItem.getName()!=null&&!"".equals(fileItem.getName())){
String filName=fileItem.getName();
//利用UUID生成伪随机字符串,作为文件名避免重复
String uuid= UUID.randomUUID().toString();
//获取文件后缀名
String suffix=filName.substring(filName.lastIndexOf("."));
//获取文件上传目录路径,在项目部署路径下的upload目录里。若想让浏览器不能直接访问到图片,可以放在WEB-INF下
String uploadPath=request.getSession().getServletContext().getRealPath("/web/userimage");
File file=new File(uploadPath);
file.mkdirs();
//写入文件到磁盘,该行执行完毕后,若有该临时文件,将会自动删除
fileItem.write(new File(uploadPath,uuid+suffix));
//生成图片在该项目下的URL以便于在页面回显
path = "http://localhost:8080"+request.getContextPath()+"/web/userimage/"+uuid+suffix;
System.out.println(path);
request.getServletContext().setAttribute("path",path);
}
else{
}
}
} catch (Exception e) {
e.printStackTrace();
}
bd.uploadImage(path,user);
response.sendRedirect("blog.jsp");
}
}
注意:经过servlet处理之后会生成图片的名称并能将其上传到本地,这时可以生成一个该图片的URL,可以将这个path封装在域对象中,当某个页面需要回显图片时便可以方便其显示。
遇到的问题
在上面已经提到,当form表单中添加了"enctype=“multipart/form-data”"属性之后,如果表单中还有除了"file"类型以外的数据类型如text时,request对象是接收不到数据的,对此的解决方法为:
代码(2)
if(处理的数据类型为file类型){
......
}else{
//System.out.println(fileItem.getFieldName()); //该name值空间中的value值
System.out.println(fileItem.getString("UTF-8"));
user = fileItem.getString("UTF-8");
user = URLDecoder.decode(user,"UTF-8");
System.out.println(user);
request.getServletContext().setAttribute("name",user);
System.out.println(path);
}
代码(3):
Servlet完整代码
package servlet;
import com.jspsmart.upload.SmartUpload;
import dao.BlogDaoImpl;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.*;
import java.net.URLDecoder;
import java.util.UUID;
import java.util.List;
@WebServlet(name="upload",urlPatterns = "/upload")
public class UploadFileServlet extends HttpServlet {
BlogDaoImpl bd = new BlogDaoImpl();
SmartUpload su = new SmartUpload();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DiskFileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(factory);
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;utf-8");
String user = null;
String path = null;
//设置缓冲区大小与临时文件目录
factory.setSizeThreshold(1024*1024*10);
File uploadTemp=new File("e:\\uploadTemp");
uploadTemp.mkdirs();
factory.setRepository(uploadTemp);
//设置单个文件大小限制
upload.setFileSizeMax(1024*1024*10);
//设置所有文件总和大小限制
upload.setSizeMax(1024*1024*30);
try {
List list=upload.parseRequest(request);
System.out.println(list);
for (FileItem fileItem:list){
if (!fileItem.isFormField()&&fileItem.getName()!=null&&!"".equals(fileItem.getName())){
String filName=fileItem.getName();
//利用UUID生成伪随机字符串,作为文件名避免重复
String uuid= UUID.randomUUID().toString();
//获取文件后缀名
String suffix=filName.substring(filName.lastIndexOf("."));
//获取文件上传目录路径,在项目部署路径下的upload目录里。若想让浏览器不能直接访问到图片,可以放在WEB-INF下
String uploadPath=request.getSession().getServletContext().getRealPath("/web/userimage");
File file=new File(uploadPath);
file.mkdirs();
//写入文件到磁盘,该行执行完毕后,若有该临时文件,将会自动删除
fileItem.write(new File(uploadPath,uuid+suffix));
path = "http://localhost:8080"+request.getContextPath()+"/web/userimage/"+uuid+suffix;
System.out.println(path);
request.getServletContext().setAttribute("path",path);
}
else{
System.out.println(fileItem.getFieldName()); //该name值空间中的value值
System.out.println(fileItem.getString("UTF-8"));
user = fileItem.getString("UTF-8");
user = URLDecoder.decode(user,"UTF-8");
System.out.println(user);
request.getServletContext().setAttribute("name",user);
System.out.println(path);
}
}
} catch (Exception e) {
e.printStackTrace();
}
bd.uploadImage(path,user);
response.sendRedirect("blog.jsp");
}
}
四.将图片路径存入数据库
代码
public void uploadImage(String path,String name){
Connection con = JDBCUtil.getConnection();
String sql = "insert into imagepath (name,path) values (?,?)";
PreparedStatement ps = null;
try {
ps = con.prepareStatement(sql);
ps.setString(1,name);
ps.setString(2,path);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}