java实现图片上传至服务器并显示,如何做?希望要具体的代码实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java实现图片上传至服务器并显示,如何做?希望要具体的代码实现相关的知识,希望对你有一定的参考价值。

目标就是通过JSP页面让用户选择本地图片文件,提交就上传到服务器保存。上传成功的话JSP页面上就显示刚上传的图片。

很简单。
可以手写IO读写(有点麻烦)。
怕麻烦的话使用FileUpload组件 在servlet里doPost嵌入一下代码
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException
response.setContentType("text/html;charset=gb2312");
PrintWriter out=response.getWriter();

//设置保存上传文件的目录
String uploadDir =getServletContext().getRealPath("/up");
System.out.println(uploadDir);
if (uploadDir == null)

out.println("无法访问存储目录!");
return;

//根据路径创建一个文件
File fUploadDir = new File(uploadDir);
if(!fUploadDir.exists())
if(!fUploadDir.mkdir())//如果UP目录不存在 创建一个 不能创建输出...

out.println("无法创建存储目录!");
return;



if (!DiskFileUpload.isMultipartContent(request))

out.println("只能处理multipart/form-data类型的数据!");
return ;


DiskFileUpload fu = new DiskFileUpload();
//最多上传200M数据
fu.setSizeMax(1024 * 1024 * 200);
//超过1M的字段数据采用临时文件缓存
fu.setSizeThreshold(1024 * 1024);
//采用默认的临时文件存储位置
//fu.setRepositoryPath(...);
//设置上传的普通字段的名称和文件字段的文件名所采用的字符集编码
fu.setHeaderEncoding("gb2312");

//得到所有表单字段对象的集合
List fileItems = null;
try

fileItems = fu.parseRequest(request);//解析request对象中上传的文件


catch (FileUploadException e)

out.println("解析数据时出现如下问题:");
e.printStackTrace(out);
return;


//处理每个表单字段
Iterator i = fileItems.iterator();
while (i.hasNext())

FileItem fi = (FileItem) i.next();
if (fi.isFormField())
String content = fi.getString("GB2312");
String fieldName = fi.getFieldName();
request.setAttribute(fieldName,content);
else
try

String pathSrc = fi.getName();
if(pathSrc.trim().equals(""))
continue;

int start = pathSrc.lastIndexOf('\\');
String fileName = pathSrc.substring(start + 1);
File pathDest = new File(uploadDir, fileName);

fi.write(pathDest);
String fieldName = fi.getFieldName();
request.setAttribute(fieldName, fileName);
catch (Exception e)
out.println("存储文件时出现如下问题:");
e.printStackTrace(out);
return;

finally //总是立即删除保存表单字段内容的临时文件

fi.delete();




注意 JSP页面的form要加enctype="multipart/form-data" 属性, 提交的时候要向服务器说明一下 此页面包含文件。

如果 还是麻烦,干脆使用Struts 的上传组件 他对FileUpload又做了封装,使用起来更傻瓜化,很容易掌握。

-----------------------------
以上回答,如有不明白可以联系我。
参考技术A 有两种方法一是用上传的组建jspSmartUpload的Request,
还有一种不用组建,但在form表单中不能加入ENCTYPE= "multipart/form-data "
我给你的案例吧
建立后台数据库

if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[p]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[p]
GO
CREATE TABLE [dbo].[p] (

[picid] [int] IDENTITY (1, 1) NOT NULL ,

[picname] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,

[pic] [image] NULL

) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

3.向数据库存储二进制图片

启动Dreamweaver MX后,新建一个JSP文件。其代码如下所示。

<%@ page contentType="text/html;charset=gb2312"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()
+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">

<title>My JSP 'InputImage.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css" href="styles.css">

-->

</head>

<body>

<form action="testimage.jsp" method="POST"><br>

题目<input name="picname" type="text"><br>

图片<input name="pic" type="file"><br>

<input type="Submit" name="button1" value="提交"><br>

</form>

</body>

</html>

将此文件保存为InputImage.jsp文件,其中testimage.jsp文件是用来将图片数据存入数据库的,具体代码如下所示:

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="java.sql.*" %>

<%@ page import="java.util.*"%>

<%@ page import="java.text.*"%>

<%@ page import="java.io.*"%>

<jsp:useBean id="conn" scope="page" class="dbconn.DBResult"/>

<%
String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+
":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">

<title>My JSP 'testimage.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css" href="styles.css">

-->

</head>

<body>

<%
request.setCharacterEncoding("gb2312");

//建立Statement对象

String picname=request.getParameter("picname");

String pic=request.getParameter("pic");

//获得所要显示图片的标题、存储路径、内容,并进行中文编码

FileInputStream str=new FileInputStream(pic);

String sql="insert into p(picname,pic) values(?,?)";

PreparedStatement pstmt=conn.getPreparedStatement(sql);

pstmt.setString(1,picname);

pstmt.setBinaryStream(2,str,str.available());

pstmt.execute();

//将数据存入数据库

out.println("Success,You Have Insert an Image Successfully");

%>

</body>

</html>

4. 网页中动态显示图片

接下来我们要编程从数据库中取出图片,其代码如下所示。

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="java.sql.*" %>

<%@ page import="java.util.*"%>

<%@ page import="java.text.*"%>

<%@ page import="java.io.*"%>

<jsp:useBean id="conn" scope="page" class="dbconn.DBResult"/>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+
":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">

<title>My JSP 'testimageout.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css" href="styles.css">

-->

</head>

<body>

<%

int id= Integer.parseInt(request.getParameter("picid"));

String sql = "select pic from p WHERE picid="+id;

ResultSet rs=conn.getResult(sql);

while(rs.next())



ServletOutputStream sout = response.getOutputStream();

//图片输出的输出流

InputStream in = rs.getBinaryStream(1);

byte b[] = new byte[0x7a120];

for(int i = in.read(b); i != -1;)


sout.write(b);

//将缓冲区的输入输出到页面

in.read(b);



sout.flush();

//输入完毕,清除缓冲

sout.close();



%>

</body>

</html>

将此文件保存为testimageout.jsp文件。下一步要做的工作就是使用HTML标记:

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="java.sql.*" %>

<%@ page import="java.util.*"%>

<%@ page import="java.text.*"%>

<%@ page import="java.io.*"%>

<jsp:useBean id="conn" scope="page" class="dbconn.DBResult"/>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+
":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<base href="<%=basePath%>">

<title>My JSP 'lookpic.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

<!--

<link rel="stylesheet" type="text/css" href="styles.css">

-->

</head>

<body>

<%

String sql = "select * from p";

ResultSet rs=conn.getResult(sql);

while(rs.next())



%>

<ccid_file values="testimageout" % />" width="100" height="100">

<br>

<%



rs.close();

%>

</body>

</html>
参考技术B 自己上apache找common-fileupload,此包可单独用,struts也把它整合了,官网上的例子简单明了,另外楼上那位的smartupload已经破产许久了...一上传大文件就卡死 参考技术C 第一步,在SQL-Server中创建表

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[picTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[picTable]
GO

CREATE TABLE [dbo].[picTable] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[pic] [image] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

第二步:上传页面
<%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title>
index
</title>
</head>
<body bgcolor="#ffffff">
<form action="saveit.jsp" enctype="multipart/form-data" method="POST">
<input type="file" name="image" size="20" maxlength="20"/><p>
<input type="submit" value="上传"/>
</form>
<br>
<a href="servlet3">显示图片</a>
</body>
</html>

3.保存图片的jsp
<%@ page contentType="text/html; charset=GBK" import="upload.*"%>
<html>
<head>
<title>
jsp1
</title>
</head>
<body bgcolor="#ffffff">
<%
db.addPic(pageContext,application,out);
out.println("图片添加成功!");
%>
<br>
<a href="index.jsp">返回继续添加</a>
</a>
</body>
</html>

调用一个JavaBean中的addpic方法

package upload;
import com.jspsmart.upload.*;
import javax.servlet.jsp.*;
import javax.servlet.*;
import java.io.*;
import javax.servlet.http.*;

import java.sql.*;
public class db
private static Connection conn=null;
public db()

public static void InitConnection(String dbName)



public static void addPic(PageContext pageContext,ServletContext application,JspWriter out)
try

//将上传文件存入应用程序目录
SmartUpload su=new SmartUpload();
su.initialize(pageContext);
su.setMaxFileSize(5*1024*1024);
su.upload();//到服务器的内存
com.jspsmart.upload.File f=su.getFiles().getFile(0);
String filename=f.getFileName();
filename=application.getRealPath("/")+filename;
f.saveAs(filename);

//通过流方式,读取文件,存入数据库中
java.io.File file=new java.io.File(filename);
FileInputStream fis=new FileInputStream(file);

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String strCon="jdbc:odbc:pubs";
conn=DriverManager.getConnection(strCon,"sa","");
Statement st=conn.createStatement();
String sql="insert into picTable (pic,type) values(?,?)";
//预编译命令
PreparedStatement ps=conn.prepareStatement(sql);
ps.setBinaryStream(1,fis,(int)file.length());
ps.setString(2,filename.substring(filename.lastIndexOf(".")+1));
ps.executeUpdate();
//删除文件
fis.close();
boolean isOK=file.delete();
if(!isOK)

System.out.println("文件删除失败");

ps.close();

catch(Exception e)

System.out.println(e.getMessage());


public static void display(HttpServletResponse response) throws Exception

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String strCon="jdbc:odbc:pubs";
conn=DriverManager.getConnection(strCon,"sa","");
Statement st=conn.createStatement();

//显示图片
String sql = "select [type],pic from picTable";
st=conn.createStatement();
ResultSet rs = st.executeQuery(sql);
response.reset();
while(rs.next())

String type = rs.getString(1);

//读取二进制流,将文件内容写入二进制文件
InputStream in = rs.getBinaryStream(2);
byte[] buffer =new byte[1444];
int byteread=0;
while ((byteread=in.read(buffer))!=-1)

response.getOutputStream().write(buffer,0,byteread);


response.getOutputStream().close();
rs.close();



显示图片调用display

Tip:记住别忘了导包:jspsmartupload 这个包。
参考技术D 用FCKEditor多好,一个插件搞定一系列需求

如何优雅的将 图片文字上传至服务器?

本文目录

前言

可能很多小伙伴们在学习 JAVA WEB 的时候,都或多或少的接触过 IO 流等相关方面的知识,从最简单的在 JAVA 环境下实现文件的复制拷贝,然后进阶到WEB环境的文件传输、拷贝、存储。最后高级点到整合第三方存储服务来实现,甚至还有将文件存储在数据库的(不推荐)。本文的目的在于向大家介绍,实战中是如何实现这个需求的

需求分析

下图是我从若依管理系统截取的一张图片,可以看到这个界面需要将公告标题、公告内容(为了突出本文要点,公告内容只能是图片)、公告类型存储到数据库中。提交参数有文字、图片,如果是你会怎么开发这个接口呢?

  1. 文字内容好办,实体类封装相关字段,然后操作数据库进行数据插入即可,图片也好办,存到服务器或者外接第三方存储服务,然后将返回的 IMG 的地址存到数据库中即可
  2. 问题一:后端接口如何同时接收图片、文字
  3. 问题二:如果是将文件存储到服务器内,绝对路劲 or 相对路劲?傻傻分不清楚。如果是外接第三方存储服务则不必操心这个问题

下文将针对如上俩个问题展开论述~

@RequestPart 解决问题一

当前请求如果请求头中包含 multipart/form-data ,@RequestPart 会自动将接收到的 JSON 字符串封装成一个对象接收

指定 JSON 字符串的传输形式为 application/json

后端接收方式

@Slf4j
@RestController
@RequestMapping
public class FileController 
    @PostMapping(value = "/uploadFile")
    public R uploadFile(@RequestPart("user") User user,
                        @RequestPart("assignPath") String assignPath,
                        @RequestPart("file") MultipartFile file) 
        try 
            String path = FileUploadUtils.uploadFile(null, file, assignPath);
            user.setImg(path);
            System.err.println(user.toString());
            //模拟数据入库操作
            boolean update = true;
            if (update) return R.ok(path);
            //数据入库失败应删除文件资源,避免造成服务器压力过大问题
            FileUploadUtils.deleteFile("更新成功:" + path);
            return R.failed("更新失败");
         catch (Exception e) 
            e.printStackTrace();
            log.error(e.getMessage());
            return R.failed("内部服务器错误");
        
    


@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
class User implements Serializable 
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    private String img;
    private String name;
    private String age;

ResourceUtils 解决问题二

ResourceUtils 是 Spring 为我们提供的一个工具类,可以通过它可以获取项目类路劲下的文件,通过这些文件继而可以定位到文件的绝对路劲,删除文件调用 new File(url).delete() 即可。下面是我写的一个工具类

@Slf4j
public class FileUploadUtils 

    public static String getFileType(String fileName) 
        int separatorIndex = fileName.lastIndexOf(".");
        if (separatorIndex < 0) 
            return "";
        
        return fileName.substring(separatorIndex + 1).toLowerCase();
    

    /**
     * @param serverName 服务名(网关中配置的服务名,服务没走网关传null即可)
     * @param file       要保存的文件
     * @param targetPath 指定存储路劲(默认保存项目的/static/file路劲下)
     * @return
     * @throws IOException
     */
    public static String uploadFile(String serverName, MultipartFile file, String targetPath) throws IOException 
        IdWorker idWorker = new IdWorker();
        String type = getFileType(file.getOriginalFilename());
        File path = new File(ResourceUtils.getURL("classpath:").getPath());
        if (!path.exists()) path = new File("");
        if (null == targetPath) targetPath = "/static/file";
        else targetPath = "/static/" + targetPath + "/";
        File upload = new File(path.getAbsolutePath(), targetPath);
        if (!upload.exists()) upload.mkdirs();
        String newFileName = idWorker.nextId() + "." + type;
        String url = "";
        if (serverName != null) url = "/" + serverName + targetPath + newFileName;
        else url = targetPath + newFileName;
        log.info(upload.getAbsolutePath() + File.separator + newFileName);
        FileUtils.copyInputStreamToFile(file.getInputStream(), new File(upload.getAbsolutePath() + File.separator + newFileName));
        return url;
    

    public static Boolean deleteFile(String url) throws IOException 
        File path = new File(ResourceUtils.getURL("classpath:").getPath());
        File file = new File(path.getAbsolutePath(), url);
        boolean delete = file.delete();
        return delete;
    


效果

数据可以成功入库、并且存储到服务器

如何限制上传文件的大小并返回优雅的提示?

首先在yml配置文件中添加如下配置,上传的文件超过我们配置的30MB,接口将会拒绝此次请求,会抛出异常

spring:
  servlet:
    multipart:
      enabled: true
#      单次请求大小不能超过30MB
      max-request-size: 30MB
#      多个文件总大小不能超过30MB
      max-file-size: 30MB

为了提高用户体验,我们最好补货一下这个异常,返回给用户:上传文件过大的提示

@Slf4j
@RestControllerAdvice
public class ExceptionApect 
    @ExceptionHandler(value = MultipartException.class)
    public @ResponseBody
    Result handleBusinessException(Exception ex) 
        String msg;
        if (ex instanceof MaxUploadSizeExceededException) 
            log.error(ex.getMessage());
            msg = "上传文件过大";
         else 
            msg = "上传文件失败";
        
        return Result.success(msg);
    


附录:多文件上传实现

@ApiOperation(value = "多文件上传", notes = "")
@PostMapping(value = "/uploadFiles")
public Result skillApplyFile(HttpServletRequest request) throws IOException 
    MultipartRequest multipartRequest = (MultipartRequest) request;
    String assignPath = request.getParameter("assignPath");
    Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
    Collection<MultipartFile> multipartFiles = fileMap.values();
    ArrayList<String> urls = new ArrayList<>();
    for (MultipartFile file : multipartFiles) 
        String url = FileUploadUtils.uploadFile(null, file, assignPath);
        urls.add(url);
    
    return Result.success(urls);

❥(_-)❥(-)❥(_-)❥(-)❥(_-)❥(-)❥(_-)❥(-)如果觉着本篇文章对你有帮助~可以点个赞哟❥(_-)❥(-)❥(_-)❥(-)❥(_-)❥(-)❥(^-)

以上是关于java实现图片上传至服务器并显示,如何做?希望要具体的代码实现的主要内容,如果未能解决你的问题,请参考以下文章

Java Servlet图片上传至指定文件夹并显示图片

如何优雅的将 图片文字上传至服务器?

Android实现本地上传图片并设置为圆形头像

linux下如何实现web上传并显示图片

如何优雅的将 图片文字上传至服务器?

java实现图片转化成base64字符串前端页面直接显示