Je souhaite ajouter une fonction de téléchargement à mon application Spring Boot. c'est mon upload Rest Controller
package org.sid.web;
import Java.io.BufferedOutputStream;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.nio.file.Files;
import Java.nio.file.Path;
import Java.nio.file.Paths;
import Java.util.ArrayList;
import Java.util.List;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.sid.entities.FileInfo;
@RestController
public class UploadController {
@Autowired
ServletContext context;
@RequestMapping(value = "/fileupload/file", headers = ("content-type=multipart/*"), method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<FileInfo> upload(@RequestParam("file") MultipartFile inputFile) {
FileInfo fileInfo = new FileInfo();
HttpHeaders headers = new HttpHeaders();
if (!inputFile.isEmpty()) {
try {
String originalFilename = inputFile.getOriginalFilename();
File destinationFile = new File(
context.getRealPath("C:/Users/kamel/workspace/credit_app/uploaded") + File.separator + originalFilename);
inputFile.transferTo(destinationFile);
fileInfo.setFileName(destinationFile.getPath());
fileInfo.setFileSize(inputFile.getSize());
headers.add("File Uploaded Successfully - ", originalFilename);
return new ResponseEntity<FileInfo>(fileInfo, headers, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
}
} else {
return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
}
}
}
mais en testant cela dans postman avec insertion http: // localhost: 8082/fileupload/file et en ajoutant un fichier au corps, j'ai l'erreur suivante: "exception": "org.springframework.web.multipart .support.MissingServletRequestPartException "," message ":" La partie de requête requise 'le fichier' n'est pas présent ",
Voici comment devrait ressembler votre demande dans Postman:
Mon exemple de code:
application.properties
#max file and request size
spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=11MB
Classe d'application principale:
Application.Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Classe de contrôleur de repos:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
@RequestMapping("/fileupload")
public class MyRestController {
@RequestMapping(value = "/file", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody String myService(@RequestParam("file") MultipartFile file,
@RequestParam("id") String id) throws Exception {
if (!file.isEmpty()) {
//your logic
}
return "some json";
}
}
pom.xml
//...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
//...
Sauf en ce qui concerne les autres réponses publiées, le problème pourrait être dû à l'absence de prise en charge en plusieurs parties pour le servlet traitant la demande (DispatcherServlet de spring dans le cas de l'application Spring).
Cela peut être corrigé en ajoutant un support en plusieurs parties à la servlet de répartition dans la déclaration web.xml ou lors de l'initialisation (dans le cas d'une configuration basée sur des annotations)
a) config web-xml
<web-app xmlns="http://Java.Sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee
http://Java.Sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config>
<max-file-size>10485760</max-file-size>
<max-request-size>20971520</max-request-size>
<file-size-threshold>5242880</file-size-threshold>
</multipart-config>
</servlet>
</web-app>
b) pour une configuration basée sur des annotations, ceci serait le suivant:
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
final AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
final ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(appContext));
registration.setLoadOnStartup(1);
registration.addMapping("/");
File uploadDirectory = new File(System.getProperty("Java.io.tmpdir"));
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(uploadDirectory.getAbsolutePath(), 100000, 100000 * 2, 100000 / 2);
registration.setMultipartConfig(multipartConfigElement);
} }
Nous devons ensuite fournir un résolveur en plusieurs parties capable de résoudre les fichiers envoyés en tant que demande en plusieurs parties. Pour la configuration d'annotation, cela peut être fait de la manière suivante:
@Configuration
public class MyConfig {
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
Pour une configuration printanière basée sur XML, vous devez ajouter ce bean au contexte via la déclaration de déclaration de balise:
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />
Alternativement au résolveur standard multipart de spring, vous pouvez utiliser l'implémentation à partir de communs. De cette façon, une dépendance supplémentaire est requise:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000"/>
</bean>
Dans votre méthode, vous avez spécifié comme ceci@RequestParam("file")
. Par conséquent, il s'attend à ce que la clé soit file
. C'est assez évident dans le message d'exception. Utilisez ce nom dans le champ Key
de Postman lorsque vous téléchargez un fichier.
Plus d'informations ici scénario de test d'intégration et téléchargement de fichier
J'avais aussi un problème similaire et le fichier pièce de demande d'erreur n'était pas présent. Mais je me suis rendu compte par la suite que j'avais dans mon application ce code qui posait problème:
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new
CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000000);
return multipartResolver;
}
J'ai enlevé ceci et cela a commencé à fonctionner pour RequestPart et RequestParam. Voir la question connexe ci-dessous:
https://forum.predix.io/questions/22163/multipartfile-parameter-is-not-present-error.html