首先在项目根目录下创建一个Servlet包,在这个包中创建两个Servlet类,一个用来完成图片的增删改查(ImageServlet),一个用来展示图片的详细内容(ImageShowServlet).
一、创建 ImageServlet
这个类的 doPost 对应插入图片,doGet 对应查看图片信息,doDelete 对应删除图片。
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doDelete(req, resp);
}
}
同时把这个类加到web.xml中。
ImageServlet
api.ImageServlet
ImageServlet
/image
二、实现ImageServlet.doPost
这个方法对应上传图片,这里需要用到 Commons.FileUpload,可以在Maven仓库中找到这个包,并且使用maven下载。
commons-fileupload
commons-fileupload
1.4
实现doPost方法
// 1. 获取到图片相关的元信息(Image对象), 并写入数据库
// a) 创建 factory 对象和 upload 对象
// b) 使用 upload 对象解析请求
// c) 对请求信息进行解析, 转换成 Image 对象
// d) 将 Image 对象写入数据库中
// 2. 获取到图片内容, 写入到磁盘中
// 3. 设置返回的响应结果
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
// 上传图片
resp.setContentType("application/json; charset=utf8");
PrintWriter writer = resp.getWriter();
// 1. 获取到图片相关的元信息(Image对象), 并写入数据库
// a) 创建 factory 对象和 upload 对象
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = null;
// b) 使用 upload 对象解析请求
try {
items = upload.parseRequest(req);
} catch (FileUploadException e) {
e.printStackTrace();
resp.setStatus(500);
writer.println("{ \"ok\" : false, \"reason\" : \"请求解析失败\"}");
return;
}
// c) 对请求信息进行解析, 转换成 Image 对象
// 一个请求可以上传一个文件, 也能上传多个文件
// 当前只考虑上传一个的情况
FileItem item = items.get(0);
Image image = new Image();
image.setImageName(item.getName());
image.setSize((int)item.getSize());
SimpleDateFormat df = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
image.setUploadTime(df.format(new Date()));
// TODO 计算 MD5 的方法暂时不写
image.setMd5("AABBCCDD");
image.setContentType(item.getContentType());
// 引入时间戳, 让文件名唯一
image.setPath(PATH_BASE + System.currentTimeMillis() + "_" + image.getImageName());
// d) 将 Image 对象写入数据库中
ImageDao imageDao = new ImageDao();
imageDao.insert(image);
// 2. 获取到图片内容, 写入到磁盘中
File file = new File(image.getPath());
try {
item.write(file);
} catch (Exception e) {
e.printStackTrace();
resp.setStatus(500);
// 注意, 此处可能出现脏数据的情况, 比如数据库插入成功, 但是这里文件写入失败
writer.println("{ \"ok\" : false, \"reason\" : \"文件写入失败\"}");
return;
}
// 3. 设置返回的响应结果
resp.setStatus(200);
// 先不使用 GSON 来构建 Json 字符串
writer.println("{ \"ok\": true }");
}
实现ImageServlet.doGet
这里分两种情况,一个是获取所有图片的信息,一个是获取单个图片信息。根据请求中是否带有image_id 参数来决定。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
// 这个一定要放在上面(否则不生效)
resp.setContentType("application/json;charset=UTF-8");
String image_id = req.getParameter("image_id");
if (image_id == null || image_id.equals("")) {
// 获取所有图片信息
doSelectAll(req, resp);
} else {
// 获取指定图片信息
doSelectOne(Integer.parseInt(imageId), resp);
}
}
实现doSelectAll
// 1. 创建 ImageDao 对象并从数据库查找数据
// 2. 将查找到的数据转换成 JSON 格式的字符串
// 3. 结果字符串写入到 resp 对象中
private void doSelectAll(HttpServletRequest req, HttpServletResponse resp) throws
IOException {
ImageDao imageDao = new ImageDao();
List images = imageDao.selectAll();
String respString = gson.toJson(images);
resp.setContentType("application/json; charset=utf8");
resp.getWriter().write(respString);
}
实现doSelectOne
// 1. 创建 ImageDao 对象并从数据库查找数据
// 2. 将查找到的数据转换成 JSON 格式的字符串
// 3. 结果字符串写入到 resp 对象中
private void doSelectOne(Integer imageId, HttpServletResponse resp) throws IOException {
ImageDao imageDao = new ImageDao();
Image image = imageDao.selectOne(imageId);
if (image == null) {
resp.setStatus(404);
resp.getWriter().write("{ \"ok\": false, \"reason\":\"imageId 不存在\"}");
return;
}
resp.setStatus(200);
String respString = gson.toJson(image);
resp.getWriter().write(respString);
}
实现ImageSeverlet.doDelete
// 1. 获取请求中的 imageId
// 2. 创建 ImageDao 对象, 查找对应的 Image 对象
// 3. 删除数据库中的数据
// 4. 删除磁盘上的文件
// 5. 写回响应
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
resp.setContentType("application/json; charset=utf8");
// 1. 获取请求中的 imageId
String imageId = req.getParameter("imageId");
if (imageId == null || "".equals(imageId)) {
resp.setStatus(404);
resp.getWriter().write("{ \"ok\": false, \"reason\": \"imageId 解析失败\" }");
return;
}
// 2. 创建 ImageDao 对象, 查找对应的 Image 对象
ImageDao imageDao = new ImageDao();
Image image = imageDao.selectOne(Integer.parseInt(imageId));
if (image == null) {
resp.setStatus(404);
resp.getWriter().write("{ \"ok\": false, \"reason\": \"imageId 不存在\" }");
return;
}
// 3. 删除数据库中的数据
imageDao.delete(Integer.parseInt(imageId));
// 4. 删除磁盘上的文件
File file = new File(image.getPath());
file.delete();
// 5. 写回响应
resp.getWriter().write("{ \"ok\": true }");
}
实现ImageShowServlet
实现展示图片详细内容接口
// 1. 解析请求中的 imageId
// 2. 查找数据库, 找到对应的 path
// 3. 从文件中读图片数据, 别忘记设置 content-type
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
// 1. 解析请求中的 imageId
String imageId = req.getParameter("imageId");
if (imageId == null || "".equals(imageId)) {
resp.setContentType("application/json; charset=utf8");
resp.setStatus(404);
resp.getWriter().write("{ \"ok\": false, \"reason\": \"解析 imageId 失败\" }");
return;
}
// 2. 查找数据库, 找到对应的 path
ImageDao imageDao = new ImageDao();
Image image = imageDao.selectOne(Integer.parseInt(imageId));
if (image == null) {
resp.setContentType("application/json; charset=utf8");
resp.setStatus(404);
resp.getWriter().write("{ \"ok\": false, \"reason\": \"imageId 不存在\" }");
return;
}
// 3. 从文件中读图片数据, 别忘记设置 content-type
resp.setContentType(image.getContentType());
File file = new File(image.getPath());
// 使用字节流读取文件(图片是二进制文件, 不适合使用字符流)
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buffer = new byte[1024];
OutputStream outputStream = resp.getOutputStream();
while (true) {
int len = fileInputStream.read(buffer);
if (len == -1) {
break;
}
outputStream.write(buffer);
}
fileInputStream.close();
outputStream.close();
}
修改web.xml
ImageShowServlet
api.ImageShowServlet
ImageShowServlet
/imageShow