Je fais un démarrage à ressort REST. J'essaie de créer un contrôleur de téléchargement de formulaire en plusieurs parties qui gérera ensemble les données du formulaire et le téléchargement d'un fichier. Voici mon code de contrôleur pour le moment:
@RequestMapping(value = "", method = RequestMethod.POST, headers="Content-Type=multipart/form-data")
@PreAuthorize("hasRole('ROLE_MODERATOR')")
@ResponseStatus(HttpStatus.CREATED)
public void createNewObjectWithImage(
/*@RequestParam(value="file", required=true) MultipartFile file,
@RequestParam(value="param_name_1", required=true) final String param_name_1,
@RequestParam(value="param_name_2", required=true) final String param_name_2,
@RequestParam(value="param_name_3", required=true) final String param_name_3,
@RequestParam(value="param_name_4", required=true) final String param_name_4,
@RequestParam(value="param_name_5", required=true) final String param_name_5*/
@ModelAttribute ModelDTO model,
BindingResult result) throws MyRestPreconditionsException {
//ModelDTO model = new ModelDTO(param_name_1, param_name_2, param_name_3, param_name_4, param_name_5);
modelValidator.validate(model, result);
if(result.hasErrors()){
MyRestPreconditionsException ex = new MyRestPreconditionsException(
"Model creation error",
"Some of the elements in the request are missing or invalid");
ex.getErrors().addAll(
result.getFieldErrors().stream().map(f -> f.getField()+" - "+f.getDefaultMessage()).collect(Collectors.toList()));
throw ex;
}
// at the moment, model has a MultipartFile property
//model.setImage(file);
modelServiceImpl.addNew(model);
}
J'ai essayé les deux avec l'annotation @ModelAttribute et l'envoi des paramètres de demande, mais ces deux méthodes ont échoué.
Voici la demande que j'envoie:
---------------------------acebdf13572468
Content-Disposition: form-data; name="file"; filename="mint.jpg"
Content-Type: image/jpeg
<@INCLUDE *C:\Users\Lazaruss\Desktop\mint.jpg*@>
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_1”
string_value_1
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_2”
string_value_2
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_3”
string_value_3
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_4”
string_value_4
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_5”
string_value_5
---------------------------acebdf13572468--
Ma demande est apatride et utilise la sécurité de printemps avec les autorités. Dans mon package de sécurité, j'ai inclus la classe AbstractSecurityWebApplicationInitializer
public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
J'utilise également un StandardServletMultipartResolver dans ma classe @Configuration
Et dans mon WebInitializer, j'ajoute ce code:
MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/tmp",
3 * 1024 * 1024, 6 * 1024 * 1024, 1 * 512 * 1024);
apiSR.setMultipartConfig(multipartConfigElement);
Lorsque j'essaie d'utiliser le contrôleur avec le code commenté (annotations @RequestParams), j'obtiens une erreur 404 introuvable. Et lorsque j'essaie d'utiliser le contrôleur avec l'annotation @ModuleAttribute, l'objet modèle est vide.
J'avais un problème similaire. Lorsque vous souhaitez envoyer Object
+ Multipart
. Vous devez (ou du moins je ne connais pas d'autre solution) rendre votre contrôleur comme ça:
public void createNewObjectWithImage(@RequestParam("model") String model, @RequestParam(value = "file", required = false) MultipartFile file)
Et puis: Convertissez la chaîne en votre objet en utilisant:
ObjectMapper mapper = new ObjectMapper();
ModelDTO modelDTO = mapper.readValue(model, ModelDTO.class);
peut recevoir des objets et des fichiers
@PostMapping(value = "/v1/catalog/create", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
public void createNewObjectWithImage(
@RequestPart ModelTO modelTO,
@RequestPart MultipartFile image)
ModelTO
public class ModelTO {
private String name;
public ModelTO() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
et exemple de boucle:
curl -X POST "https://your-url.com/v1/catalog/create" -H "accept: application/json;charset=UTF-8" -H "Content-Type: multipart/form-data" -F "image=@/pathtoimage/powerRager.jpg;type=image/jpeg" -F "modelTO={\"name\":\"White\"};type=application/json;charset=utf-8"
Postman et les autres logiciels ne prennent pas en charge l'envoi de type application/json pour les paramètres de données de formulaire.