사진 업로드 기능은 힘든 작업이 아니어야 하지만, 대부분의 어린이 신발은 로컬(또한 tomcat/jboss 서버)에 업로드되며, 사진 이름 변경(한자 왜곡) 문제를 고려하지 않습니다.
본 블로그에 업로드된 사진들은 실제 프로젝트를 기반으로 제작되었으며 Windows, Linux 서버 모두에서 사용 가능한 nginx 사진 서버를 사용하고 있습니다.
Jsp 페이지: 파일 컨트롤, 숨겨진 컨트롤(사용자 정의 카테고리 폴더를 만드는 데 사용됨) 및 버튼(업로드 버튼)이 필요합니다.
<div> <p class="ui-tips">上传头像会自动生成头像缩略图片,您也可以拖动大图的裁剪区域,调整缩图内容。</p> <p class="ui-tips">支持JPG、GIF、PNG等图片格式 推荐尺寸:180*180像素</p> <input type="file" id="fileCoursePoster" style="display: none;" name="fileCoursePoster" /> <span id="errorCoursePoster" style="color: red; display: none;">请上传图片!</span> <input type="button" value="上传头像" class="btn btn-sm btn-normal"> <input type="hidden" id="imageType" name="imageType"> </div>
Js: js ajaxfileupload를 도입해야 합니다.
function upLoad(){ document.getElementById("imageType").value = "headPicture"; //图片分类,自定义类型,是海报还是个人头像 $("#fileCoursePoster").click(); } function uploadCoursePoster() { var imageType = document.getElementById("imageType").value; var studentId=$("#studentId").val(); $.ajaxFileUpload({ url : "/itoo-jrkj-student-web/media/uploadImages", secureuri : false, data : { "studentId" : studentId, "imageType" : imageType }, fileElementId : "fileCoursePoster",// 文件选择框的id属性 dataType : 'json', success : function(data) { $("#imgCoursePoster").attr( "src", "http://123.56.120.25:8888/apple/" + data); $('#headPic').val(data); alert("上传成功!"); }, error : function(XMLHttpRequest, textStatus, errorThrown) { alert("上传失败!"); } }); }
컨트롤러:
// 上传个人头像--生成图片路径并将路径保存到数据库 @RequestMapping(value = "media/uploadImages", produces = "text/plain;charset=UTF-8") @ResponseBody public void uploadImages(HttpServletRequest request, HttpServletResponse response) throws IllegalStateException, IOException { // 上传到指定的文件夹中,imageType为文件夹的名字 String imageType = request.getParameter("imageType").toString(); //文件夹名,便于图片分类 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; String fileName = "";//图片的名字 Calendar date = Calendar.getInstance(); //以图片类别+日期规划图片文件夹层级 SimpleDateFormat format1 = new SimpleDateFormat("yyyy"); SimpleDateFormat format2 = new SimpleDateFormat("MM"); SimpleDateFormat format3 = new SimpleDateFormat("dd"); String year = format1.format(date.getTime()); String month = format2.format(date.getTime()); String day = format3.format(date.getTime()); // 上传的图片存储的路径,格式如下: //------------------要先将文件传入本机Jboss下的jboss3.1/bin文件夹中,因为File获得图片的绝对路径是自己定位到这儿了 String uploadServicePath = ""; String filePath=""; for (Iterator it = multipartRequest.getFileNames(); it.hasNext();) { String key = (String) it.next(); MultipartFile mulfile = multipartRequest.getFile(key); fileName = mulfile.getOriginalFilename(); //获取上传图片的文件名,以便得到其在jboss中的路径 //获取存在服务器下的图片的绝对路径 File getFilePath=new File(fileName);//要根据图片名字获取路径 filePath=getFilePath.getAbsolutePath();//获取Jboss服务器bin路径 File file = new File(filePath); mulfile.transferTo(file);//保存 } File imagefile = new File(filePath); //TODO:创建ftp客户端 --读配置文件 FTPClient ftpClient = new FTPClient(); ftpClient.setControlEncoding("GBK"); String hostname = "xxx.xxx.xxx.xxx"; //FTP服务器主机ip int port = 21;//FTP服务器端口,默认就是21 String username = "apple"; //FTP服务器用户名(可以有多个) String password = "apple123";//FTP服务器密码 try { //链接ftp服务器 ftpClient.connect(hostname, port); //登录ftp ftpClient.login(username, password); int reply = ftpClient.getReplyCode(); //ftp服务状态码 System.out.println("reply返回码是:"+reply); //如果reply返回230就算成功了,如果返回530密码用户名错误或当前用户无权限。 if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); return ; } ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 保存图片的相对路径到阿里云服务器 fileName=UUID.randomUUID().toString()+".jpg";//自定义图片名,也能防止汉字的干扰 uploadServicePath ="uploadImage/" + imageType + "/" + year + "/" + month+day+"/"+fileName; //上传到服务器的路径 //在nginx上创建文件夹,一次只能创建一级,所以建多级要分多次 ftpClient.makeDirectory("uploadImage");//什么的都不写的情况下,默认在root目录下创建文件夹,此处在nginx/apple/uploadImage下,apple文件夹是用户名,创建用户时自动建好的 ftpClient.makeDirectory("uploadImage/"+imageType); ftpClient.makeDirectory("uploadImage/"+imageType+ "/" + year); ftpClient.makeDirectory("uploadImage/"+imageType+ "/" + year +"/"+month+day); InputStream input = new FileInputStream(imagefile); ftpClient.storeFile(uploadServicePath, input);//文件你若是不指定就会上传到root目录下 input.close(); ftpClient.logout(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException ioe) { ioe.printStackTrace(); } } } // 根据id更新个人信息 Student student = new Student(); String studentId = request.getParameter("studentId"); student = studentBean.findStudentById(studentId, dataBaseName); student.setDataBaseName(dataBaseName); student.setHeadPic(uploadServicePath); if (!studentBean.updateHeadPicture(student)) { uploadServicePath = "error"; } System.out.println("realPath-------------" + uploadServicePath); JacksonJsonUntil jacksonJsonUntil = new JacksonJsonUntil(); jacksonJsonUntil.beanToJson(response, uploadServicePath); } // 读取往期图片 @RequestMapping(value = "media/readImages", produces = "text/plain;charset=UTF-8") public void readImage(HttpServletRequest request, HttpServletResponse response) { // 或:从服务器中的相对位置读取图片 // String imagesPath // =request.getSession().getServletContext().getRealPath("/")+request.getParameter("imagesPath"); String imagesPath = request.getParameter("imagesPath"); System.out.println("imagesPath-------------------" + imagesPath); try { File file = new File(imagesPath); if (file.exists()) { DataOutputStream temps = new DataOutputStream( response.getOutputStream()); DataInputStream in = new DataInputStream(new FileInputStream( imagesPath)); byte[] b = new byte[2048]; while ((in.read(b)) != -1) { temps.write(b); temps.flush(); } in.close(); temps.close(); } } catch (Exception e) { e.printStackTrace(); } }
해결책: 컨트롤러에서 확인하고 원본 사진 이름의 유형, 즉 ".xxx" 또는 ".xxxx"가 jpg/의 네 가지 유형에 속하지 않는 경우 차단합니다. jpeg/png/gif, 다만 적절하게 이름을 바꾸고 원본 이미지 유형 접미사를 추가하는 것은 허용되지 않습니다.
위 내용은 관련 내용을 포함하여 이미지 업로드(Windows/Linux에서 사용 가능)의 uploadFile nginx 구현을 소개합니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.