使用multipart请求处理文件上传

21 篇文章 0 订阅
3 篇文章 0 订阅

很好的文章,赞。



在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石——SpringMVC其中的一个优势。Spring通过对ServletAPI的HttpServletRequest接口进行扩展,使其能够很好地处理文件上传。扩展后的接口名为org.springframework.web.multipart.MultipartHttpServletRequest,其内容如清单7-31所示。

清单7-31 org.springframework.web.multipart.MultipartHttpServletRequest接口

interface MultipartHttpServletRequest extends HttpServletRequest{

public MultipartFile getFile(String name);

public Map getFileMap();

public Iterator getFileNames();

}



如清单所示,MultipartHttpServletRequest接口简单地扩展了默认的HttpServletRequest接口,并提供一些用来处理请求文件的方法。

7.10.1  使用multipart请求

实际上只要发现一个multipart请求,就表明在控制器实例中存在一个实现MultipartHttpServletRequest接口的request对象。我们可以通过清单7-31所示的方法来访问multipart请求中的上传文件,不过在处理上传文件之前,先来看一下上传表单的内容,如清单7-32所示。

清单7-32  上传表单示例

<form action="upload"enctype="multipart/form-data">

<input type="file" name="myFile"/>

<input type="submit" value="Upload! "/>

</form>

粗体显示的是需要注意的部分,实际上一个上传表单只需要满足如下两点。

enctype属性的属性值设为multipart/form-data。

input的type属性的属性值设为file。

在前面的示例中,<input>标签中属性type的值为file,且name属性的值为myFile,之所以需要name属性值,是因为在使用接口MultipartHttpServletRequest的getFile方法时需要使用name属性的值。例如在清单7-33中,代码中的upload操作会从请求中读取上传文件。

清单7-33  读取上传文件

def upload = {

def file = request.getFile('myFile')

// 处理该文件

}

注意getFile方法不会返回一个java.io.File的实例,而是返回org.springframework.web.multipart.MultipartFile的一个实例,关于org.springframework.web.multipart.MultipartFile的详细信息,请参考清单7-34。如果在请求中没有找到文件则getFile方法返回null。

清单7-34 org.springframework.web.multipart.MultipartFile接口

interface MultipartFile {

public byte[] getBytes();

public String getContentType();

public java.io.InputStream getInputStream();

public String getName();

public String getOriginalFilename();

public long getSize();

public boolean isEmpty();

public void transferTo(java.io.File dest);

}

在MultipartFile接口中定义了如下很多有用的方法。

使用getSize()方法获得文件长度,以此决定允许上传的文件大小。

使用isEmpty()方法判断上传文件是否为空文件,以此决定是否拒绝空文件。

使用getInputStream()方法将文件读取为java.io.InputStream流对象。

使用getContentType()方法获得文件类型,以此决定允许上传的文件类型。

使用transferTo(dest)方法将上传文件写到服务器上指定的文件。

例如,如果上传的文件不为空并且大小不小于1024字节,那么可以按照清单7-35中的代码来实现。

清单7-35  文件上传示例

def upload = {

def file = request.getFile('myFile')

if(file && !file.empty&& file.size < 1024){

file.transferTo( new java.io.File("/local/server/path/${file.name}" ) )

}

}

直接使用MultipartHttpServletRequest实例可以用来管理文件上传,但实际应用常常需要读取文件内容。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用multipart请求上传文件,你可以使用Java的`HttpURLConnection`类或者一些常用的HTTP客户端库(如Apache HttpClient或OkHttp)。下面是使用`HttpURLConnection`进行multipart文件上传的示例代码: ```java import java.io.*; import java.net.HttpURLConnection; import java.net.URL; public class Main { public static void main(String[] args) { String targetUrl = "http://example.com/upload"; String filePath = "/path/to/your/file.jpg"; try { URL url = new URL(targetUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=---------------------------1234567890"); File file = new File(filePath); String boundary = "---------------------------1234567890"; String CRLF = "\r\n"; OutputStream outputStream = connection.getOutputStream(); PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream)); // 写入文件数据 writer.append("--").append(boundary).append(CRLF); writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"").append(CRLF); writer.append("Content-Type: " + HttpURLConnection.guessContentTypeFromName(file.getName())).append(CRLF); writer.append(CRLF).flush(); FileInputStream fileInputStream = new FileInputStream(file); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = fileInputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush(); fileInputStream.close(); // 写入结束标记 writer.append(CRLF).flush(); writer.append("--").append(boundary).append("--").append(CRLF); writer.close(); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 上传成功 System.out.println("文件上传成功!"); } else { // 上传失败 System.out.println("文件上传失败!Response Code: " + responseCode); } connection.disconnect(); } catch (IOException e) { e.printStackTrace(); } } } ``` 在上述示例中,我们首先指定了目标URL和要上传的文件的路径。然后,我们创建了一个`URL`对象,并使用`openConnection()`方法获取一个`HttpURLConnection`对象。 我们设置了一些请求属性,如`setDoOutput(true)`表示允许输出流发送数据,`setRequestMethod("POST")`表示使用POST方法发送请求,`setRequestProperty()`用于设置请求头的Content-Type属性以指定multipart/form-data类型。 接下来,我们打开输出流,并使用`PrintWriter`向输出流写入数据。我们首先写入multipart请求的开始标记,并指定文件的表单字段名、文件名和Content-Type。然后,我们从文件中读取数据并将其写入输出流。 最后,我们写入multipart请求的结束标记,并关闭writer。然后,我们可以通过调用`getResponseCode()`方法获取响应码来判断文件是否成功上传。 请替换示例代码中的`targetUrl`和`filePath`为你自己的目标URL和文件路径。确保你有权限访问目标URL,并根据需要修改请求头的Content-Type属性。 需要注意的是,该示例仅适用于单个文件的上传。如果你需要上传多个文件,可以在循环中重复上述过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值