1
votes

Mapper en tant que paramètre dans la demande de publication de l'API Rest

J'ai créé une API avec un paramètre Map , comme ceci:

@RequestMapping(value = "upload", method = RequestMethod.POST)
public ResponseEntity<String> handleContactsFileUpload(@RequestParam("file") MultipartFile file,
                                                       @RequestParam("name") String name,
                                                       @RequestParam("campaignAppItemId") Long campaignAppItemId,
                                                       @RequestParam("fileColumnHeaders") Map<String,Integer> fileColumnHeaders) throws Exception {
    if (file == null)
        return new ResponseEntity<>("No file uploaded", HttpStatus.BAD_REQUEST);
    contactService.handleContactsFile(file, name, campaignAppItemId,fileColumnHeaders);
    return new ResponseEntity<>("File uploaded successfully", HttpStatus.OK);
}

J'essaye d'appeler ceci via Postman:

J'ai passé le fileColumnHeaders dans Body-> Form Data comme dans la capture d'écran.

Ensuite, j'ai reçu un message comme celui-ci dans Postman:

Échec de la conversion de la valeur de type 'java.lang.String' en type requis 'java.util.Map'; l'exception imbriquée est java.lang.IllegalStateException: Impossible de convertir la valeur de type 'java.lang.String' en type requis 'java.util.Map': aucun éditeur ou stratégie de conversion correspondant n'a été trouvé.

Quelqu'un sait pourquoi ce message est venu? Comment pouvons-nous passer une carte en tant que paramètre dans la demande d'API Rest? Comment pouvons-nous faire passer une carte via Postman?


8 commentaires

Qu'avez-vous publié? Pouvez vous donner un exemple?


Copie possible de Comment envoyer la carte en tant que paramètre de requête lors d'un appel GET


J'ai joint la capture d'écran du facteur. S'il te plaît vérifie le


ngueno Mais c'est un appel POST


@anaskodur et en quoi est-ce différent de GET en ce qui concerne @RequestParam ? Osez chercher?


et pourquoi le fichier est-il envoyé en tant que @RequestParam ? Cela ne semble pas correct ...


@Pijotrek En fait, c'est une demande de publication. Le fichier peut être envoyé en tant que RequestParam. Sauf le paramètre de la carte, tous fonctionnent.


Le fait que quelque chose «fonctionne» ne signifie pas que cela doit être fait de cette façon. Vous pouvez également implémenter un point de terminaison de connexion et utiliser GET avec des informations d'identification en tant que @RequestParam sans SSL . Cela fonctionnera également.


4 Réponses :


4
votes

Vous pouvez utiliser @RequestBody au lieu de @RequestParam pour les cartes et autres types de données et objets non triviaux - de cette façon, spring mappera le JSON représentant votre paramètre de carte à un domaine, qui est ensuite sérialisable et peut être converti en objet java.


3 commentaires

Pouvons-nous utiliser RequestBody et RequestParam ensemble dans une demande? Si oui, comment pouvons-nous les faire passer par le facteur?


À en juger par votre capture d'écran, vous passez déjà votre carte dans le corps de la requête.


Mais quand j'ai donné RequestBody pour la carte, j'ai reçu un message comme celui-ci dans postman 'Content type' multipart / form-data; boundary = ---------------------- ---- 8189‌ 89541995583398579446‌; charset = UTF-8 'non pris en charge'



0
votes

Je pense que cela pourrait fonctionner:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

Mettez tous les autres paramètres dans le corps, mais ajoutez le fileColumnHeaders à l'URL comme ceci:

/ upload / firstName = 1; lastName = 2; address = 3; phone = 4

Vous aurez également besoin de cette configuration supplémentaire:

@RequestMapping(value = "upload/{fileColumnHeaders}", method = RequestMethod.POST)
public ResponseEntity<String> handleContactsFileUpload(@RequestParam("file") MultipartFile file,
                                                       @RequestParam("name") String name,
                                                       @RequestParam("campaignAppItemId") Long campaignAppItemId,
                                                       @MatrixVariable Map<String,Integer> fileColumnHeaders) throws Exception {
    if (file == null)
        return new ResponseEntity<>("No file uploaded", HttpStatus.BAD_REQUEST);
    contactService.handleContactsFile(file, name, campaignAppItemId,fileColumnHeaders);
    return new ResponseEntity<>("File uploaded successfully", HttpStatus.OK);
}

p >


0 commentaires

1
votes

Premièrement, vous créez un objet DTO pour obtenir toutes les données de votre demande.

@RequestMapping(value = "upload", method = RequestMethod.POST)
public ResponseEntity<String> handleContactsFileUpload(FormDataDTO formDataDTO){
    // your logic code here
}

Deuxièmement, vous pouvez mapper FormDataDTO à partir de votre demande sans aucune annotation:

public class FormDataDTO {

    private MultipartFile file;

    private String name;

    private Long campaignAppItemId;

    private Map<String,Integer> fileColumnHeaders;

    // getters, setters
}


0 commentaires

2
votes

... Ou créez simplement un convertisseur:

@Component
@RequiredArgsConstructor
public class StringToMapConverter implements Converter<String, Map<String, Object>> {

  private final ObjectMapper objectMapper;

  @Override
  public Map<String, Object> convert(String source) {
    try {
      return objectMapper.readValue(source, new TypeReference<Map<String, String>>() {
      });
    } catch (final IOException e) {
      return null;
    }
  }

}


0 commentaires