在本文中,我们将为您详细介绍spring:文件上传RESTFULWeb服务的相关知识,并且为您解答关于spring实现文件上传的疑问,此外,我们还会提供一些关于ConsumingRESTfulWeb服
在本文中,我们将为您详细介绍spring:文件上传RESTFUL Web服务的相关知识,并且为您解答关于spring实现文件上传的疑问,此外,我们还会提供一些关于Consuming RESTful Web服务、GWT + Spring MVC(RESTful Web服务)、java – Spring:文件上传RESTFUL Web Service、java – 为什么Spring RESTful Web服务每次都需要不同的时间来完成的有用信息。
本文目录一览:- spring:文件上传RESTFUL Web服务(spring实现文件上传)
- Consuming RESTful Web服务
- GWT + Spring MVC(RESTful Web服务)
- java – Spring:文件上传RESTFUL Web Service
- java – 为什么Spring RESTful Web服务每次都需要不同的时间来完成
spring:文件上传RESTFUL Web服务(spring实现文件上传)
我正在使用Spring 4.0为RESTFUL Web服务创建POC。如果仅传递String或任何其他基本数据类型,则效果很好。
@RequestMapping(value="/upload/file", method=RequestMapping.post)public String uploadFile(@RequestParam("fileName", required=false) String fileName){ logger.info("initialization of object"); //---------------------------------------- System.out.Println("name of File : " + fileName); //----------------------------------------}
这很好。但是,如果我想将字节流或文件对象传递给函数,如何编写具有这些参数的函数?以及如何编写具有传递字节流功能的Client?
@RequestMapping(value="/upload/file", method=RequestMapping.post)public String uploadFile(@RequestParam("file", required=false) byte [] fileName){ //--------------------- // }
我尝试了此代码,但收到415错误。
@RequestMapping(value = "/upload/file", method = RequestMethod.POST, consumes="multipart/form-data")public @ResponseBody String uploadFileContentFromBytes(@RequestBody MultipartFormDataInput input, Model model) { logger.info("Get Content. "); //------------ }
客户端代码-使用apache HttpClient
private static void executeClient() { HttpClient client = new DefaultHttpClient(); HttpPost postReqeust = new HttpPost(SERVER_URI + "/file"); try{ // Set Various Attributes MultipartEntity multipartEntity = new MultipartEntity(); multipartEntity.addPart("fileType" , new StringBody("DOCX")); FileBody fileBody = new FileBody(new File("D:\\demo.docx"), "application/octect-stream"); // prepare payload multipartEntity.addPart("attachment", fileBody); //Set to request body postReqeust.setEntity(multipartEntity); HttpResponse response = client.execute(postReqeust) ; //Verify response if any if (response != null) { System.out.println(response.getStatusLine().getStatusCode()); } } catch(Exception ex){ ex.printStackTrace(); }
答案1
小编典典您可以如下创建您的休息服务。
@RequestMapping(value="/upload", method=RequestMethod.POST) public @ResponseBody String handleFileUpload( @RequestParam("file") MultipartFile file){ String name = "test11"; if (!file.isEmpty()) { try { byte[] bytes = file.getBytes(); BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(name + "-uploaded"))); stream.write(bytes); stream.close(); return "You successfully uploaded " + name + " into " + name + "-uploaded !"; } catch (Exception e) { return "You failed to upload " + name + " => " + e.getMessage(); } } else { return "You failed to upload " + name + " because the file was empty."; } }
对于客户端,请执行以下操作。
import java.io.File;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpVersion;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.mime.MultipartEntity;import org.apache.http.entity.mime.content.ContentBody;import org.apache.http.entity.mime.content.FileBody;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.params.CoreProtocolPNames;import org.apache.http.util.EntityUtils;public class Test { public static void main(String[] args) throws Exception { HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost("http://localhost:8080/upload"); File file = new File("C:\\Users\\Kamal\\Desktop\\PDFServlet1.pdf"); MultipartEntity mpEntity = new MultipartEntity(); ContentBody cbFile = new FileBody(file, "multipart/form-data"); mpEntity.addPart("file", cbFile); httppost.setEntity(mpEntity); System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); HttpEntity resEntity = response.getEntity(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } if (resEntity != null) { resEntity.consumeContent(); } httpclient.getConnectionManager().shutdown(); }}
Consuming RESTful Web服务
此篇指南带你走进创建一个consume一个RESTful web服务应用的步骤。
What You Will Build
你将使用Spring的RestTemplate
构建一个应用来获得一个在https://quoters.apps.pcfone.io/api/random
中随机的Spring Boot引用。
What You Need
- 大约15分钟@H_301_14@
- 你喜欢的文本编辑器或IDE@H_301_14@
- JDK 1.8 以上@H_301_14@
- Graddle 4+ 或 Maven 3.2+@H_301_14@
- 你也可以直接将代码导入进你的IDE
- Spring Tool Suite (STS)@H_301_14@
- InteelliJ IDEA@H_301_14@
How to complete this guide
正如Spring大多数指南一样,你可以从头开始并且完成每一个步骤或者你可以绕开你已经熟悉的基本设置。无论哪种方式,你最终都是完成代码。
为了从头开始,移步到Starting with Spring Initializr
。
为了跳过基础,做如下步骤:
- 下载并解压这篇指南的原仓库,或者使用GIt克隆
git clone https://github.com/spring-guides/gs-consuming-rest.git
@H_301_14@ - 进入(cd)
gs-consuming-rest/initial
@H_301_14@ - 移步到
Fetching a REST Resource
@H_301_14@
当你完成以后,你可以对照gs-consuming-rest/complete
代码检查你的结果。
Starting with Spring Initializr
你可以使用预初始化项目点击Generate来下载ZIP文件。这一项目被配置为适合本篇指南。
为了手动初始化项目:
- 浏览https://start.spring.io/。这个服务拉取了你的应用所有需要的依赖并且已经为了做了多数配置。@H_301_14@
- 选择Gradle或Maven与你想使用的语言。本文假设你选择Java。@H_301_14@
- 点击
Dependencies
并选择Spring Web
。@H_301_14@ - 点击Generate。@H_301_14@
- 下载ZIP文件,这是一个为你的选择配置好的网络应用文件。@H_301_14@
如果你的IDE整合了Spring Initializr,你可以从你的IDE完成此步骤
你也可以从GitHub中fork此项目使用你的IDE或者编辑器打开。
Fetching a REST Resource
随着项目设置完成之后,你可以创建一个单一应用:consumes a RESTful 服务。
一个RESTful服务已经被建立在https://quoters.apps.pcfone.io/api/random。它随机地抓取关于Spring Boot的引用并且以JSON文档返回。
如果你通过浏览器或curl请求这个URL,你会受到一个JSON文档,如下所示:
{
type: "success",
value: {
id: 10,
quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
}
}
当通过浏览器或curl抓取,这足够简单但是并没有什么用。
一个非常有用的consume REST web服务方式是以编程方式进行的。为了帮助你完成这个任务,Spring提供了一个方便的模板类,称之为RestTemplate
。RestTemplate
使得与大多数RESTful服务的交互成为一个单行的咒语。并且它甚至可以绑定这些数据与自定义域类型(custom domain types)。
首先,你需要创建一个域类(domain class)来包含你需要的数据。如下所示,你可以使用Quote
类(src/main/java/com/example/consumingrest/Quote.java
)作为你的域类(domain class)。
package com.example.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnkNown = true)
public class Quote {
private String type;
private Value value;
public Quote() {
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
@Override
public String toString() {
return "Quote{" +
"type='" + type + '\'' +
", value=" + value +
'}';
}
}
这个简单的java类有少量属性以及对应的getter方法。使用来自于Jackson的JSON库的@JsonIgnoreProperties
注解来表明不在此类型的属性应该被忽略。
为了直接将你的数据和你的自定义类型绑定,你需要指定变量名与从API返回的JSON文档里的key一致。如果你的变量名和JSON文档中的key不一致,你可以使用@JsonProperty
注解来指定JSON文档中的key。(此篇示例每一个变量名与JSON key一致,所以你不需要在此注解。)
你还需要一个额外的类,嵌入进引用本身内部。Value
类src/main/java/com/example/consumingrest/Value.java
如下所示:
package com.example.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnkNown = true)
public class Value {
private Long id;
private String quote;
public Value() {
}
public Long getId() {
return this.id;
}
public String getQuote() {
return this.quote;
}
public void setId(Long id) {
this.id = id;
}
public void setQuote(String quote) {
this.quote = quote;
}
@Override
public String toString() {
return "Value{" +
"id=" + id +
", quote='" + quote + '\'' +
'}';
}
}
这使用了相同的注解但是映射到其它数据字段。
Finishing the Application
Initializr创建了一个带有main()
方法的类(src/main/java/com/example/consumingrest/ConsumingRestApplication.java
),如下所示:
package com.example.consumingrest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConsumingRestApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumingRestApplication.class, args);
}
}
现在,你需要添加几个其它事物到ConsumingRestApplication
类,来使其显示来自Spring RESTful源的引用。你需要添加:
- 日志器(logger):将日志发送输出(在本文是输出到终端)。@H_301_14@
RestTemplate
使用Jackson库处理输入的数据。@H_301_14@CommandLineRunner
用来启动运行RestTemplate
(获取引语)。@H_301_14@
如下展示了完成后的ConsumingRestApplication
类(src/main/java/com/example/consumingrest/ConsumingRestApplication.java
):
package com.example.consumingrest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumingRestApplication {
private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);
public static void main(String[] args) {
SpringApplication.run(ConsumingRestApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"https://quoters.apps.pcfone.io/api/random", Quote.class);
log.info(quote.toString());
};
}
}
Running the Application
你可以在命令行以Gradle或Maven运行应用程序。你也可以构建一个单一可执行的jar包,其中包含所有必须的依赖、类以及资源并且运行。构建一个可执行jar可以易于传输、版本和部署服务作为应用,贯穿至整个开发周期,穿插于不同环境等等。
如果你使用Gradle,你可以通过使用./gradlew bootRun
来运行应用程序。或者说,你可以使用./gradlew build
来构建jar包,然后运行jar包,如下命令:
java -jar build/libs/gs-consuming-rest-0.1.0.jar
如果你使用Maven,你可以通过./mvnw spring-boot:run
来运行应用程序。或者说,你可以使用./mvnw clean package
来构建jar包,通过如下命令执行jar包。
java -jar target/gs-consuming-rest-0.1.0.jar
此处步骤描述了创建一个可执行jar包。你也可以构造一个经典的WAR文件。
你应该看到类似如下输出的随机的引语:
2019-08-22 14:06:46.506 INFO 42940 --- [ main] c.e.c.ConsumingRestApplication : Quote{type='success', value=Value{id=1, quote='Working with Spring Boot is like pair-programming with the Spring developers.'}}
如果你看到了
Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.consumingrest.Quote]
错误,有一种可能就是你正在一个无法连接后端服务(发送JSON)的环境。也许你正在一个公司代理中。尝试设置http.proxyHost
和http.proxyPort
适合你的环境值的系统变量。
GWT + Spring MVC(RESTful Web服务)
我一直在思考如何使用GWT设置Spring MVC 3.0(更具体地说是REST功能)。也就是说,我不再想要使用GWT
RPC,通信将通过REST进行。问题是我对Spring框架还很陌生,而我发现的唯一教程却是使用JSP,这正是我遇到的问题。有没有办法在没有JSP页面的情况下使用Spring?
GWT视图?
java – Spring:文件上传RESTFUL Web Service
如果我们只传递String或任何其他基本数据,它可以正常工作.
@RequestMapping(value="/getcontent/file",method=RequestMapping.post) public String getFileContents(@RequestParam("fileName",required=false) String fileName){ logger.info("initialization of object"); //---------------------------------------- System.out.Println("name of File : " + fileName); //---------------------------------------- }
这工作正常
但是如果我要传递字节流或文件对象功能,那么我可以用这些参数来写这个函数吗?并且我如何写客户端提供传递字节流?
@RequestMapping(value="/getcontent/file",method=RequestMapping.post) public String getFileContents(@RequestParam("file",required=false) byte [] fileName){ //--------------------- // }
我试过这个代码,但是得到415错误.
@RequestMapping(value = "/getcontent/file",method = RequestMethod.POST,consumes="multipart/form-data") public @ResponseBody String getContentFromBytes(@RequestBody MultipartFormDataInput input,Model model) { logger.info("Get Content. "); //------------ }
客户端代码 – 使用apache HttpClient
private static void executeClient() { HttpClient client = new DefaultHttpClient(); HttpPost postReqeust = new HttpPost(SERVER_URI + "/file"); try{ // Set VarIoUs Attributes multipartentity multipartentity = new multipartentity(); multipartentity.addPart("fileType",new StringBody("DOCX")); FileBody fileBody = new FileBody(new File("D:\\demo.docx"),"application/octect-stream"); // prepare payload multipartentity.addPart("attachment",fileBody); //Set to request body postReqeust.setEntity(multipartentity); HttpResponse response = client.execute(postReqeust) ; //Verify response if any if (response != null) { System.out.println(response.getStatusLine().getStatusCode()); } } catch(Exception ex){ ex.printstacktrace(); }
解决方法
@RequestMapping(value="/upload",method=RequestMethod.POST) public @ResponseBody String handleFileUpload( @RequestParam("file") multipartfile file){ String name = "test11"; if (!file.isEmpty()) { try { byte[] bytes = file.getBytes(); bufferedoutputstream stream = new bufferedoutputstream(new FileOutputStream(new File(name + "-uploaded"))); stream.write(bytes); stream.close(); return "You successfully uploaded " + name + " into " + name + "-uploaded !"; } catch (Exception e) { return "You Failed to upload " + name + " => " + e.getMessage(); } } else { return "You Failed to upload " + name + " because the file was empty."; } }
而客户端做如下.
import java.io.File; import org.apache.http.httpentity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.multipartentity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; public class Test { public static void main(String[] args) throws Exception { HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost("http://localhost:8080/upload"); File file = new File("C:\\Users\\Kamal\\Desktop\\PDFServlet1.pdf"); multipartentity mpEntity = new multipartentity(); ContentBody cbFile = new FileBody(file,"multipart/form-data"); mpEntity.addPart("file",cbFile); httppost.setEntity(mpEntity); System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); httpentity resEntity = response.getEntity(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } if (resEntity != null) { resEntity.consumeContent(); } httpclient.getConnectionManager().shutdown(); } }
java – 为什么Spring RESTful Web服务每次都需要不同的时间来完成
我有一个简单的spring启动应用程序和一个控制器类.
我的控制器内的一个简单方法:
@RequestMapping(value = "/heartbeat",method = RequestMethod.GET)
public ResponseEntity
我从Postman调用这个方法,我可以看到完成这个方法所需的时间在每个调用中都是不同的.
例如28ms,70ms,15ms ……
如果我们谈论毫秒就可以了,但我注意到在更大的Web服务中,这种差异更大,有时甚至是几秒钟.
我想这是正常的但是造成这种情况的原因是什么?
最佳答案
有许多因素可能导致这种行为.大多数时候它是可以解释的.
假设您正在本地设置上测试Web服务,可能会出现以下情况:
1.其他后台任务
在您的计算机上运行的后台任务可能会在其使用的资源上激增,这也会影响您的Web服务的执行.
2.网络状态
网络可能被不同的应用程序使用,因此您可能会得到稍微延迟的响应.
3.延迟客户
像Postman这样的客户端本身可能需要一些处理来发送请求或接受响应.这也归功于整体响应时间.
您的案例可能是上述案例中的一个,或者实际上是其他内容,这只是为了让您了解可能是哪些类型/域名的贡献因素.
今天的关于spring:文件上传RESTFUL Web服务和spring实现文件上传的分享已经结束,谢谢您的关注,如果想了解更多关于Consuming RESTful Web服务、GWT + Spring MVC(RESTful Web服务)、java – Spring:文件上传RESTFUL Web Service、java – 为什么Spring RESTful Web服务每次都需要不同的时间来完成的相关知识,请在本站进行查询。
本文标签: