自己動手寫一個java版簡單云相冊
動手寫一個java版簡單云相冊,實現(xiàn)的功能是:
用戶可以一次上傳一個至多個文件。
用戶可以下載其他人上傳的圖片。
用戶可以查看其他所有人的圖片。
用戶只能刪除通過自己IP上傳的圖片。
用到的技術(shù):
文件上傳下載、設(shè)計模式、Dom4j、xPath等。
先看下2個頁面:
源代碼:
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <servlet> <servlet-name>UploadServlet</servlet-name> <servlet-class>cn.hncu.servlets.UploadServlet</servlet-class> </servlet> <servlet> <servlet-name>cloudPhotoServlet</servlet-name> <servlet-class>cn.hncu.servlets.cloudPhotoServlet</servlet-class> </servlet> <servlet> <servlet-name>DownServlet</servlet-name> <servlet-class>cn.hncu.servlets.DownServlet</servlet-class> </servlet> <servlet> <servlet-name>DelServlet</servlet-name> <servlet-class>cn.hncu.servlets.DelServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/upload</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>cloudPhotoServlet</servlet-name> <url-pattern>/cloudPhoto</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>DownServlet</servlet-name> <url-pattern>/servlet/DownServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>DelServlet</servlet-name> <url-pattern>/servlet/DelServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>chx云相冊</title> <script type="text/javascript"> function delFile(input){ table = input.parentElement.parentElement.parentElement;//table.nodeName TBODY table.removeChild(input.parentElement.parentElement); } var t=1; function addFile(input){ tr = input.parentElement.parentElement; //alert(tr.nodeName); var str = "<td>選擇文件:</td>"+ "<td> <input type='file' name='file"+t+"'> </td> "+ "<td>文件說明:</td>"+ "<td> <input type='text' name='text"+t+"'> </td> "+ "<td> <input type='button' value='刪除文件' onclick='delFile(this)'> </td>"; tr.insertAdjacentHTML("beforeBegin",str); } function move(){ window.location.href="/myPhoto/cloudPhoto"; } </script> <style type="text/css"> #font{ color:red; } </style> </head> <body> <h1><font id="font">相冊上傳:</font></h1> <form action="/myPhoto/upload" method="post" enctype="multipart/form-data"> <table border="1px;double;#ff0000"> <tr> <td>選擇文件:</td> <td> <input type="file" name="file1"> </td> <td>文件說明:</td> <td> <input type="text" name="text1"> </td> <td> <input type="button" value="刪 除 文 件" onclick="delFile(this)"> </td> </tr> <tr> <td colspan=2> <input type="submit" value="上 傳 文 件"> </td> <td colspan=3> <input type="button" value="添 加 文 件" onclick="addFile(this)"> </td> </tr> </table> </form> <form action="/myPhoto/cloudPhoto" method="post" enctype="multipart/form-data"> <table border="1px;double;#ff0000"> <tr> <td colspan=5><input type="submit" value="進(jìn) 入 云 相 冊" onclick="move()"></td> </tr> </table> </form> </body> </html>
photo.xml:
<?xml version="1.0" encoding="UTF-8"?> <photos> </photos>
MyUtils.java:
package cn.hncu.utils; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; public class MyUtils { /** * @return 獲取UUID */ public static String getUUID(){ return UUID.randomUUID().toString().replace("-", ""); } /** * @param uuid * @return 通過uuid,獲得打散后的路徑 */ public static String getDir(String uuid){ String dir1 = Integer.toHexString( uuid.hashCode() & 0xf ); String dir2 = Integer.toHexString( (uuid.hashCode() & 0xf0)>>4 ); return "/"+dir1+"/"+dir2; } //日期時間格式 private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); /** * @return 返回的是上傳的時候的日期時間 */ public static String getCurrentDateTime(){ return sdf.format(new Date()); } }
Dom4jFactory.java:
package cn.hncu.utils; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class Dom4jFactory { private static Document dom=null; private static String path; //靜態(tài)塊!只會運行一次!特點是在類加載的時候就執(zhí)行 static{ try { SAXReader sax = new SAXReader(); //因為我們的資源已經(jīng)從myelipse中發(fā)布到tomcat服務(wù)器中了,所以跟原來的純Java項目不一樣了。 //利用當(dāng)前類找到它的類加載器,然后通過該類加載器再去獲得資源路徑 path = Dom4jFactory.class.getClassLoader().getResource("photo.xml").getPath(); //getClassLoader()返回:加載此對象所表示的類或接口的類加載器 //public URL getResource(String name)返回:讀取資源的 URL 對象;如果找不到該資源,或者調(diào)用者沒有足夠的權(quán)限獲取該資源,則返回 null。 //此方法首先搜索資源的父類加載器;如果父類加載器為 null,則搜索的路徑就是虛擬機的內(nèi)置類加載器的路徑。 //public String getPath()獲取此 URL 的路徑部分。 System.out.println(path); dom = sax.read(new FileInputStream(path)); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (DocumentException e) { throw new RuntimeException(e); } } /** * @return 獲取相冊的Document */ public static Document getDocument(){ return dom; } /** * 進(jìn)行photo.xml的保存,保存到本地 */ public static boolean save(){ try { XMLWriter w = new XMLWriter(new FileOutputStream(path)); w.write(dom); w.close(); return true; } catch (UnsupportedEncodingException e) { return false; } catch (FileNotFoundException e) { return false; } catch (IOException e) { return false; } } public static boolean del(String uuid){ Node node = dom.selectSingleNode("[@uuid='"+uuid+"']"); if(node==null){ return false; } node.getParent().remove(node); return true; } /** * 測試用 * @param args */ public static void main(String[] args){ System.out.println( getDocument() ); } }
PhotoModel.java-值對象
package cn.hncu.domain; /** * 值對象封裝 * @author 陳浩翔 * 2016-7-24 */ public class PhotoModel { private String uuid;//uuid private String realName="";//圖片真實文件名(上傳時的文件名) private String ext;//后綴名 private String dir;//打散后的路徑 private String dateTime;//上傳文件的時間 private String ip;//上傳者的IP private String desc;//文件的說明 public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } public String getExt() { return ext; } public void setExt(String ext) { this.ext = ext; } public String getDir() { return dir; } public void setDir(String dir) { this.dir = dir; } public String getDateTime() { return dateTime; } public void setDateTime(String dateTime) { this.dateTime = dateTime; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override public String toString() { return "PhotoModel [uuid=" + uuid + ", realName=" + realName + ", ext=" + ext + ", dir=" + dir + ", dateTime=" + dateTime + ", ip=" + ip + ", desc=" + desc + "]"; } }
PhotoDao.java:
package cn.hncu.photoDao.Dao; import java.util.List; import cn.hncu.domain.PhotoModel; public interface PhotoDao { /** * @param photo * @return 數(shù)據(jù)的保存 */ public boolean save(PhotoModel photo); /** * @return 返回所所有的圖片信息 */ public List<PhotoModel> getAll(); /** * @param uuid * @return 通過uuid 查找那個被封裝的值對象 */ public PhotoModel getSingleByUuid(String uuid); /** * @param uuid * @return 通過uuid刪除photos.xml中該圖片的信息 */ public boolean deleteXml(String uuid); /** * @param dir * @return 通過路徑刪除服務(wù)器磁盤中該圖片的信息 */ public boolean deleteFile(String pathFileName); }
PhotoSerImpl.java:
package cn.hncu.photoDao.impl; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import cn.hncu.domain.PhotoModel; import cn.hncu.photoDao.Dao.PhotoDao; import cn.hncu.utils.Dom4jFactory; public class PhotoSerImpl implements PhotoDao{ @Override public boolean save(PhotoModel photo) { Document dom = Dom4jFactory.getDocument(); Element root = dom.getRootElement(); //添加屬性 Element p = root.addElement("photo"); p.addAttribute("uuid", photo.getUuid()); p.addAttribute("realName", photo.getRealName()); p.addAttribute("dateTime", photo.getDateTime()); p.addAttribute("ip", photo.getIp()); p.addAttribute("ext", photo.getExt()); p.addAttribute("dir", photo.getDir()); p.addAttribute("desc", photo.getDesc()); return Dom4jFactory.save(); } @Override public List<PhotoModel> getAll() { List<PhotoModel> list = new ArrayList<PhotoModel>(); Document dom = Dom4jFactory.getDocument(); Element root = dom.getRootElement(); Iterator<Element> it = root.elementIterator("photo"); //通過DOM4J獲得photo元素的迭代器,也可以通過xPath來找到所有的 photo //List<Node> lists = dom.selectNodes("http://photo[@uuid]"); //Iterator<Node> it = lists.iterator(); while(it.hasNext()){ Element e = it.next(); PhotoModel photo = new PhotoModel(); photo.setUuid(e.attributeValue("uuid")); photo.setRealName(e.attributeValue("realName")); photo.setDateTime(e.attributeValue("dateTime")); photo.setExt(e.attributeValue("ext")); photo.setIp(e.attributeValue("ip")); photo.setDir(e.attributeValue("dir")); photo.setDesc(e.attributeValue("desc")); list.add(photo); } return list; } @Override public PhotoModel getSingleByUuid(String uuid) { List<PhotoModel> photos=getAll(); for(PhotoModel photo:photos){ if(photo.getUuid().equals(uuid)){ return photo; } } return null; } @Override public boolean deleteXml(String uuid) { Document dom = Dom4jFactory.getDocument(); Element e = (Element) dom.selectSingleNode("http://photo[@uuid='"+uuid.trim()+"']"); return e.getParent().remove(e); } @Override public boolean deleteFile(String pathFileName) { try { File file = new File(pathFileName); if(file.exists()){ file.delete(); } return true; } catch (Exception e) { return false; } } }
PhotoDaoFactory.java:
package cn.hncu.photoDao.factory; import cn.hncu.photoDao.impl.PhotoSerImpl; /** * 工廠方法 * @author 陳浩翔 * 2016-7-24 */ public class PhotoDaoFactory { public static PhotoSerImpl getPhotoDao(){ return new PhotoSerImpl(); } }
上傳-UploadServlet.java:
package cn.hncu.servlets; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import cn.hncu.domain.PhotoModel; import cn.hncu.photoDao.Dao.PhotoDao; import cn.hncu.photoDao.factory.PhotoDaoFactory; import cn.hncu.utils.Dom4jFactory; import cn.hncu.utils.MyUtils; public class UploadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().print("<h1>很抱歉,本頁面不支持GET方式訪問?。?!</h1>"); response.getWriter().print("<a href='javascript:history.go(-1)'>返回上一頁</a> "); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); final PrintWriter out = response.getWriter(); //防黑-非multipart表單提交 //使用上傳工具的方式 boolean boo = ServletFileUpload.isMultipartContent(request); if(!boo){ out.print("<h1>不支持普通表單的提交方式!</h1>"); return; } File file = new File("d:/photoCache"); if(!file.exists()){ file.mkdir(); } DiskFileItemFactory fiFactory = new DiskFileItemFactory(1024*10,file); ServletFileUpload upload = new ServletFileUpload(fiFactory); upload.setHeaderEncoding("utf-8");//設(shè)置文件名編碼 String path = getServletContext().getRealPath("/photos"); FileItem fi = null; try { List<FileItem> list = upload.parseRequest(request); PhotoModel photo = new PhotoModel();//數(shù)據(jù)封裝---需要7個屬性 photo.setRealName(""); int cont=0; for(FileItem f:list){ if(cont!=0 && cont%2==0 && !photo.getRealName().equals("")){ photo = new PhotoModel();//重新數(shù)據(jù)封裝 } fi=f; if(fi.isFormField()){//普通表單組件 //得到文件說明 String desc = fi.getString("utf-8"); photo.setDesc(desc);//#1 }else{ //防黑3-如果在file組件中不選擇文件 if(fi.getSize()==0){ photo.setRealName(""); cont++; continue; } String fileName = fi.getName(); fileName = fileName.substring( fileName.lastIndexOf("\\")+1);//真實文件名 photo.setRealName(fileName);//#2 String ext = fileName.substring(fileName.lastIndexOf("."));//擴展名 photo.setExt(ext);//#3 photo.setDateTime(MyUtils.getCurrentDateTime());//#4 photo.setIp( request.getRemoteAddr() );//#5 String uuid = MyUtils.getUUID(); photo.setUuid(uuid);//#6 photo.setDir( MyUtils.getDir(uuid) );//#7 //打散目錄 File dFile = new File(path+photo.getDir()); if(!dFile.exists()){ dFile.mkdirs(); } fi.write(new File(path+photo.getDir()+"/"+photo.getUuid()+photo.getExt())); } cont++; if(cont%2==0 && !photo.getRealName().equals("")){ PhotoDao dao = PhotoDaoFactory.getPhotoDao(); boo = dao.save(photo); //存入磁盤-法二:FileUtils.copyInputStreamToFile(in, new File(fileName2));//※2※ 把圖片文件存儲到服務(wù)器硬盤 photo = new PhotoModel();//重新數(shù)據(jù)封裝 } } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally{ if(fi!=null){ fi.delete(); } if(Dom4jFactory.save()){ out.print("<h1>上傳成功!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一頁</a> "); }else{ out.print("<h1>上傳失敗!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一頁</a> "); } } } }
顯示所有文件-cloudPhotoServlet.java
package cn.hncu.servlets; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.hncu.domain.PhotoModel; import cn.hncu.photoDao.Dao.PhotoDao; import cn.hncu.photoDao.factory.PhotoDaoFactory; public class cloudPhotoServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String pwd = (String) request.getParameter("pwd"); if ("chx".equals(pwd)) { doPost(request, response); } else { response.setContentType("text/html;charset=utf-8"); response.getWriter().print("<h1>很抱歉,你沒有權(quán)限訪問?。?!</h1>"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>CHX云相冊</TITLE></HEAD>"); out.println(" <BODY>"); out.println("<table border='1px;double;#ff0000'>"); out.println("<tr>"); out.println("<td>文件名</td>"); out.println("<td>上傳時間"); out.println("<td>文件</td>"); out.println("<td>文件說明</td>"); out.println("<td>操作</td> "); out.println("</tr>"); String tdWH = "style='width:200px; height:200px;'"; // 顯示所有圖片 PhotoDao dao = PhotoDaoFactory.getPhotoDao(); List<PhotoModel> photos = dao.getAll(); for (PhotoModel photo : photos) { String fileName = photo.getRealName(); String time = photo.getDateTime(); // 輸出圖片 String path = request.getContextPath() + "/photos/" + photo.getDir() + "/" + photo.getUuid() + photo.getExt(); // System.out.println(path); // /myPhoto/photos//7/c/a1237a48a6aa451cb22fa78b15bafcea.jpg String img = "<a href='" + path + "'><img src='" + path + "'/></a>"; String desc = photo.getDesc(); String delStr = "<a href='/myPhoto/servlet/DelServlet?uuid=" + photo.getUuid() + "'>刪除</a>"; String downStr = "<a href='/myPhoto/servlet/DownServlet?uuid=" + photo.getUuid() + "'>下載</a>"; out.println("<tr>"); out.println("<td " + tdWH + "> " + fileName + " </td>"); out.println("<td " + tdWH + ">" + time + "</td>"); out.println("<td " + tdWH + ">" + img + "</td>"); out.println("<td " + tdWH + ">" + desc + "</td>"); out.println("<td " + tdWH + ">" + delStr + " " + downStr + "</td>"); out.println("</tr>"); } out.println("<tr>"); out.println("</tr>"); out.println("</table>"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } }
刪除文件-DelServlet.java
package cn.hncu.servlets; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.hncu.domain.PhotoModel; import cn.hncu.photoDao.Dao.PhotoDao; import cn.hncu.photoDao.factory.PhotoDaoFactory; public class DelServlet extends HttpServlet { //注入 private PhotoDao dao = PhotoDaoFactory.getPhotoDao(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uuid = request.getParameter("uuid"); String ip = request.getRemoteAddr(); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); PhotoModel photo = dao.getSingleByUuid(uuid); if(photo!=null){ if(!photo.getIp().equals(ip)){ out.print("<h1>你沒有權(quán)限刪除這個文件!??!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一頁</a> "); return ; } //1.刪除數(shù)據(jù)庫中的信息 boolean boo = dao.deleteXml(uuid); if(boo){ String fileName = "photos/"+photo.getDir()+"/"+photo.getUuid()+photo.getExt(); String pathFileName = getServletContext().getRealPath(fileName); if(dao.deleteFile(pathFileName)){ //重定向到相冊頁面 response.sendRedirect("/myPhoto/cloudPhoto?pwd=chx"); }else{ out.print("<h1>無法從服務(wù)器中刪除,文件正在被占用?。?!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一頁</a> "); } }else{ out.print("<h1>該文件已經(jīng)不存在?。?!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一頁</a> "); } } } }
下載文件-DownServlet.java
package cn.hncu.servlets; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.hncu.domain.PhotoModel; import cn.hncu.photoDao.Dao.PhotoDao; import cn.hncu.photoDao.factory.PhotoDaoFactory; public class DownServlet extends HttpServlet { private PhotoDao dao = PhotoDaoFactory.getPhotoDao(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uuid = request.getParameter("uuid"); System.out.println(uuid); PhotoModel photo = dao.getSingleByUuid(uuid); System.out.println(photo); if(photo!=null){ //設(shè)置響應(yīng)頭--內(nèi)容接收程序--瀏覽器看到這個響應(yīng)頭,就會把它認(rèn)為的下載程序打開 //(如果識別迅雷那么就會自動打開迅雷,如果沒有則會打開一個“文件另存為”的對話框) response.setContentType("application/force-download"); String realName = photo.getRealName(); String agent = request.getHeader("User-Agent"); System.out.println(agent); if(agent.indexOf("Mozilla")!=-1){//火狐瀏覽器 response.setHeader("Content-Disposition", "attachment;filename="+ new String(realName.getBytes("GB2312"),"ISO-8859-1")); }else{ //解決中文亂碼問題(只要用下面一句對文件名進(jìn)行編碼就行了) realName = URLEncoder.encode(realName, "utf-8");//使用指定的編碼機制將字符串轉(zhuǎn)換為 application/x-www-form-urlencoded 格式。 response.setHeader("Content-Disposition", "attachment;filename=\""+realName+"\""); //注意:“cttachment;”不能少,否則瀏覽器會直接在新窗口中打開 } String fileName = "photos/" + photo.getDir()+"/"+photo.getUuid()+photo.getExt(); String pathFileName = getServletContext().getRealPath(fileName); InputStream in = new FileInputStream(pathFileName); OutputStream out = response.getOutputStream(); byte buf[] = new byte[2048]; int len=0; while( (len=in.read(buf))!=-1 ){ out.write(buf, 0, len); } out.close(); in.close(); }else{ response.setContentType("text/html;charset=utf-8"); response.getWriter().println("<h1>該文件已經(jīng)被刪除了</h1>"); } } }
演示結(jié)果
這個我就不演示啦,圖片在前面也有,所有的源碼我都給了。有興趣的可以自己取改進(jìn)一下咯。
其實這個還能上傳其他任意類型文件哦,因為我們沒有防護(hù)后綴名的,而且我們是用字符流傳輸,全都不會失真(可以當(dāng)云盤來處理了~~)??!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 相冊管理系統(tǒng)(Java表單+xml數(shù)據(jù)庫存儲)
- javaWEB實現(xiàn)相冊管理的簡單功能
- Android相冊效果(使用C#和Java分別實現(xiàn))
- Android拍照保存在系統(tǒng)相冊不顯示的問題解決方法
- 基于Android實現(xiàn)保存圖片到本地并可以在相冊中顯示出來
- android照相、相冊獲取圖片剪裁報錯的解決方法
- Android ViewPager相冊橫向移動的實現(xiàn)方法
- Android實現(xiàn)讀取相機(相冊)圖片并進(jìn)行剪裁
- Android 使用Gallery實現(xiàn)3D相冊(附效果圖+Demo源碼)
- 精致小巧的java相冊制作方法
相關(guān)文章
Spring中@RabbitHandler和@RabbitListener的區(qū)別詳析
@RabbitHandler是用于處理消息的方法注解,它與@RabbitListener注解一起使用,這篇文章主要給大家介紹了關(guān)于Spring中@RabbitHandler和@RabbitListener區(qū)別的相關(guān)資料,需要的朋友可以參考下2024-02-02iOS獲取AppIcon and LaunchImage''s name(app圖標(biāo)和啟動圖片名字)
這篇文章主要介紹了iOS獲取AppIcon and LaunchImage's name(app圖標(biāo)和啟動圖片名字)的相關(guān)資料,非常不錯,具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)吧2016-08-08SpringBoot使用責(zé)任鏈模式優(yōu)化業(yè)務(wù)邏輯中的if-else代碼
在開發(fā)過程中,我們經(jīng)常會遇到需要根據(jù)不同的條件執(zhí)行不同的邏輯的情況,我們可以考慮使用責(zé)任鏈模式來優(yōu)化代碼結(jié)構(gòu),使得代碼更加清晰、可擴展和易于維護(hù)2023-06-06Spring?代理?Bean?獲取不到原始?Bean?對象注解解決方法
這篇文章主要介紹了Spring?代理?Bean?獲取不到原始?Bean?對象注解解決方法,文章圍繞主題相關(guān)資料展開詳細(xì)介紹,需要的小伙伴可以參考一下2022-04-04SpringBoot+Mybatis-plus+shardingsphere實現(xiàn)分庫分表的方案
實現(xiàn)億級數(shù)據(jù)量分庫分表的項目是一個挑戰(zhàn)性很高的任務(wù),下面是一個基于Spring Boot的簡單實現(xiàn)方案,感興趣的朋友一起看看吧2024-03-03java中Sources目錄Resources目錄的區(qū)別解讀
這篇文章主要介紹了java中Sources目錄Resources目錄的區(qū)別解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12SpringBoot整合JWT框架,解決Token跨域驗證問題
Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)((RFC 7519).定義了一種簡潔的,自包含的方法用于通信雙方之間以JSON對象的形式安全的傳遞信息。2021-06-06