本rest服务教程是使用rest服务处理文件上传和下载的快速指南。我们将通过rest服务示例演示如何使用具有不同前端(AngularJS和JSP)的JAX-RS API上传和下载文件。最重要的是,我们将展示如何构建JUnit测试来测试使用RESTEasy客户端API上传的文件。
为了管理文件上载和下载,我们将使用核心JAX-RS API和Rest Easy实现,以及Apache Commons IO库中的IOUtil类。以下是我们Rest端点的源代码:
package com.mastertheboss.rest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.ResponseBuilder;
import org.apache.commons.io.IOUtils;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
@Path("/file")
public class RestFilesDemo {
@Context
private ServletContext context;
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(MultipartFormDataInput input) throws IOException {
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
// Get file data to save
List<InputPart> inputParts = uploadForm.get("attachment");
for (InputPart inputPart : inputParts) {
try {
MultivaluedMap<String, String> header = inputPart.getHeaders();
String fileName = getFileName(header);
// convert the uploaded file to inputstream
InputStream inputStream = inputPart.getBody(InputStream.class, null);
byte[] bytes = IOUtils.toByteArray(inputStream);
//String path = System.getProperty("user.home") + File.separator + "uploads";
File customDir = new File(Config.UPLOAD_FOLDER);
if (!customDir.exists()) {
customDir.mkdir();
}
fileName = customDir.getCanonicalPath() + File.separator + fileName;
writeFile(bytes, fileName);
return Response.status(200).entity("Uploaded file name : " + fileName+" . <br/> <a href='"+context.getContextPath()+"'>Back</a>").build();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
@POST
@Path("/download")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Consumes("application/x-www-form-urlencoded")
public Response downloadFileWithPost(@FormParam("file") String file) {
String path = System.getProperty("user.home") + File.separator + "uploads";
File fileDownload = new File(path + File.separator + file);
ResponseBuilder response = Response.ok((Object) fileDownload);
response.header("Content-Disposition", "attachment;filename=" + file);
return response.build();
}
@GET
@Path("/download")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadFileWithGet(@QueryParam("file") String file) {
System.out.println("Download file "+file);
File fileDownload = new File(Config.UPLOAD_FOLDER + File.separator + file);
ResponseBuilder response = Response.ok((Object) fileDownload);
response.header("Content-Disposition", "attachment;filename=" + file);
return response.build();
}
@GET
@Path("/list")
@Produces(MediaType.APPLICATION_JSON)
public List<String> listFiles() {
List<String> listFiles = new ArrayList<>();
File fileFolder = new File(Config.UPLOAD_FOLDER);
File[] list = fileFolder.listFiles();
for (File f: list) {
if (!f.isDirectory()) {
listFiles.add(f.getName());
}
}
return listFiles;
}
private String getFileName(MultivaluedMap<String, String> header) {
String[] contentDisposition = header.getFirst("Content-Disposition").split(";");
for (String filename : contentDisposition) {
if ((filename.trim().startsWith("filename"))) {
String[] name = filename.split("=");
String finalFileName = name[1].trim().replaceAll("\"", "");
return finalFileName;
}
}
return "unknown";
}
// Utility method
private void writeFile(byte[] content, String filename) throws IOException {
File file = new File(filename);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fop = new FileOutputStream(file);
fop.write(content);
fop.flush();
fop.close();
}
}
以下是所用方法的一些详细信息:
*listFiles:此方法返回Config.UPLOAD_FOLDER中可用的文件列表
*uploadFile(MultipartFormDataInput输入):此方法上载File,使用HTTP POST方法中的MULTIPART_FORM_DATA
*downloadFileWithPost(@FormParam(“file”)String文件):此方法从HTTP POST下载文件,生成二进制流,并将文件名作为Form参数传递
*downloadFileWithGet(@QueryParam(“file”)String file):此方法还下载file,但它包含filename作为Query参数
接下来,为了确保“uploads”文件夹存在,以下Context Listener将在部署应用程序后创建该文件夹:
package com.mastertheboss.rest;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.File;
@WebListener
public class WebContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
if (!new File(Config.UPLOAD_FOLDER).exists()) {
new File(Config.UPLOAD_FOLDER).mkdir();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//. . .
}
}
有几种方法可以休息我们的rest上传服务。这里我们将展示一个REST客户端集合,它可以将文件作为多部分表单数据发送。
如果您正在使用Postman测试您的REST服务,您所需要做的就是创建一个New|HTTP请求t。
从HTTP请求用户界面:
1.输入REST服务的URL(例如。http://localhost:8080/rest-文件管理器/resr/file/upload)
1.选择POST作为方法
1.在Body中选择表单数据
1.输入类型文件的键“附件”。上载“值”列中的文件
例如:
小时
最后,单击发送从Postman上传文件。
首先,创建以下索引。使用AngularJS控制器与我们的REST服务交互的jsp页面:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen" />
<script type = "text/javascript">
angular.module('app', [])
.controller('ctrl', function ($scope, $http) {
$scope.files = [];
$scope.loadData = function () {
$http({
method: 'GET',
url: '/rest-file-manager/rest/file/list'
}).then(function successCallback(response) {
$scope.files = response.data;
}, function errorCallback(response) {
console.log(response.statusText);
});
}
$scope.downloadFile = function (filename) {
$http({
method: 'GET',
url: '/rest-file-manager/rest/file/download',
params: {
file: filename
},
responseType: 'arraybuffer'
}).success(function (data, status, headers) {
headers = headers();
var contentType = headers['content-type'];
var linkElement = document.createElement('a');
try {
var blob = new Blob([data], {
type: contentType
});
var url = window.URL.createObjectURL(blob);
linkElement.setAttribute('href', url);
linkElement.setAttribute("download", filename);
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
linkElement.dispatchEvent(clickEvent);
} catch (ex) {
console.log(ex);
}
}).error(function (data) {
console.log(data);
});
};
//call loadData when controller initialized
$scope.loadData();
})
</script>
<title>REST Download demo with AngularJS</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body ng-app='app' ng-controller='ctrl'>
<h1>REST Upload/Download demo using AngularJS</h2>
<h2>Upload file</h2>
<form method="post" action="rest/file/upload"
enctype="multipart/form-data">
<input type="hidden" name="action" value="upload" /> <label>Load
your file:</label> <input type="file" name="attachment" /> <br /> <input
type="submit" value="Upload file" />
</form>
<h2>Download file</h2>
<div class="divTable blueTable">
<div class="divTableHeading">
<div class="divTableHead">File Name</div>
<div class="divTableHead">Action</div>
</div>
<div class="divTableRow" ng-repeat="file in files">
<div class="divTableCell">{{ file }}</div>
<div class="divTableCell"><a ng-click="downloadFile( file )" class="myButton">Download</a> </div>
</div>
</div>
</body>
</html>
接下来,使用以下方法部署示例应用程序:
mvn clean install wildfly:deploy
最后,下面是我们在上传示例XML文件后Rest Endpoint的工作方式:
小时
为了上传和下载文件,您还可以使用一种最简单的方法:一个包含JSP代码的HTML页面。JSP部分主要用于显示服务器上可用的文件列表:
<%@page import="java.io.*, com.mastertheboss.rest.Config" %>
<%@page import="java.util.*" %>
<%! public void GetDirectory(String a_Path, Vector a_files, Vector a_folders) {
File l_Directory = new File(a_Path);
File[] l_files = l_Directory.listFiles();
for (int c = 0; c < l_files.length; c++) {
if (l_files[c].isDirectory()) {
a_folders.add(l_files[c].getName());
} else {
a_files.add(l_files[c].getName());
}
}
}
%>
<html>
<head>
<title>Start Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>REST Upload demo</h2>
<form method="post" action="rest/file/upload"
enctype="multipart/form-data">
<input type="hidden" name="action" value="upload" /> <label>Load
your file:</label> <input type="file" name="attachment" /> <br /> <input
type="submit" value="Upload file" />
</form>
<h2>REST Download demo</h2>
<form method="POST" action="rest/file/download">
File name: <input type="text" name="file">
<input type="submit">
</form>
<h2>Current Directory $HOME/uploads:</h2>
<br/>
<%
Vector l_Files = new Vector(), l_Folders = new Vector();
GetDirectory(Config.UPLOAD_FOLDER, l_Files, l_Folders);
out.println("<ul>");
for (int a = 0; a < l_Files.size(); a++) {
out.println("<li>" + l_Files.elementAt(a).toString() + "</li>");
}
out.println("</ul>");
%>
</body>
</html>
下面是我们正在使用的简单JSP前端:
小时
最后,我们在本教程中包括一个JUnit Test类示例,它显示了其中最难的部分:使用REST Easy Client API管理多部件请求以上载文件:
package com.mastertheboss.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
import org.junit.Test;
public class TestRest {
String FILENAME="test-file.txt";
@Test
public void sendFile() throws Exception {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/rest-file-manager/rest/file/upload");
MultipartFormDataOutput mdo = new MultipartFormDataOutput();
createFile();
File filePath = new File(FILENAME);
// Check that file exists
assertTrue(filePath.exists());
mdo.addFormData("attachment", new FileInputStream(filePath),
MediaType.APPLICATION_OCTET_STREAM_TYPE,filePath.getName());
GenericEntity<MultipartFormDataOutput> entity = new GenericEntity<MultipartFormDataOutput>(mdo) {};
Response r = target.request().post( Entity.entity(entity, MediaType.MULTIPART_FORM_DATA_TYPE));
// Check that upload was successful
assertEquals(r.getStatus(), 200);
}
private void createFile() {
try {
PrintWriter writer = new PrintWriter(FILENAME, "UTF-8");
writer.println("Some text");
writer.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
型
这是pom。用于构建和部署项目的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mastertheboss</groupId>
<artifactId>rest-file-manager</artifactId>
<version>1.1</version>
<packaging>war</packaging>
<name>rest-file-manager</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.server.bom>19.0.0.Final</version.server.bom>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-jakartaee8-with-tools</artifactId>
<version>${version.server.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_4.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>rest-file-manager</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>2.0.0.Final</version>
<configuration>
<filename>${project.build.finalName}.war</filename>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>install</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<maven.test.skip>false</maven.test.skip>
</properties>
</profile>
</profiles>
</project>
要运行测试,请使用“测试”配置文件,如下所示:
$ mvn -Ptest test
最后,我们将提到,您还可以使用cURL测试文件上载:
$ curl -F file=@"/tmp/file.txt" http://localhost:8080/rest-file-manager/rest/file/upload
Successfully uploaded - file.txt
您可以在这里找到这个rest服务教程的源代码:https://github.com/fmarchioni/mastertheboss/tree/master/javaee/rest-file-manager。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
内容来源于网络,如有侵权,请联系作者删除!