web-dev-qa-db-fra.com

Renvoi de JSON en tant que réponse Spring Boot

J'essaie d'obtenir une réponse de repos en tant que json à la place, j'obtiens en tant que chaîne.

Contrôleur

@RestController
@RequestMapping("/api/")
public class someController{

  @Autowired
  private SomeService someService;

  @GetMapping("/getsome")
  public Iterable<SomeModel> getData(){
    return someService.getData();
  }
}

Service

@Autowired
private SomeRepo someRepo;

public Iterable<someModel> getData(){
  return someRepo.findAll();
}

Référentiel

public interface SomeRepo extends CrudRepository<SomeModel,Integer>{

}

Modèles

@Entity
@Table(name="some_table")
public class SomeModel{

  @Id
  @Column(name="p_col", nullable=false)
  private Integer id;
  @Column(name="s_col")
  private String name
  @Column(name="t_col")
  private String json;   // this column contains json data

  //constructors, getters and setters
}

quand je lance localhost: 8080/api/getsome je reçois:

[
 {
    "p_col":1,
    "s_col":"someName",
    "t_col":" 
{\r\n\t"school_name\":\"someSchool\",\t\r\n\t"grade\":"A\",\r\n\t\"class\": 
 [{\"course\":"abc",\t"course_name\":\"def" }]}"
  }
]

Le champ t_col renvoie une chaîne au lieu de json. Comment obtenir des objets json en réponse?

Quant à la base de données, les trois colonnes sont int, varchar et varchar.

Toute aide serait appréciée. Merci !!

4
404or505

Vous devez définir votre attribut json comme JsonNode afin que jackson puisse le lire en avant et en arrière, mais la marque est aussi @Transient afin que JPA n'essaye pas de le stocker dans la base de données.

Ensuite, vous pouvez coder getter/setter pour JPA, où vous traduisez de JsonNode en chaîne d'avant en arrière. Vous définissez un getter getJsonString qui traduit JsonNode json à String. Celui-ci peut être mappé à une colonne de table, comme 'json_string', puis vous définissez un setter où vous recevez le String de JPA et l'analysez en JsonNode qui sera disponible pour jackson, jackson le traduira ensuite en un objet json pas une chaîne comme vous le mentionnez.

@Entity
@Table(name = "model")
public class SomeModel {

  private Long id;
  private String col1;

  //  Attribute for Jackson 
  @Transient
  private JsonNode json;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getId() {
    return id;
  }

  @Column(name ="col1")
  public String getCol1() {
    return col1;
  }

  // Getter and setter for name

  @Transient
  public JsonNode getJson() {
    return json;
  }

  public void setJson(JsonNode json) {
    this.json = json;
  }

  // Getter and Setter for JPA use
  @Column(name ="jsonString")
  public String getJsonString() {
    return this.json.toString();
  }

  public void setJsonString(String jsonString) {
    // parse from String to JsonNode object
    ObjectMapper mapper = new ObjectMapper();
    try {
      this.json = mapper.readTree(jsonString);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Remarquer, @Column sont définis au niveau des gettters car nous devons indiquer à JPA d'utiliser getJsonString et JPA requiert une cohérence, donc tous les getters de la colonne doivent être marqués avec @Columns.

1
  @RequestMapping(value = "/getsome", method = RequestMethod.POST, consumes = 
  "application/json;")
 public @ResponseBody
  ModelAndView getSome(@RequestBody List<Map<String, String>> request) {
 request.stream().forEach(mapsData->{
    mapsData.entrySet().forEach(mapData -> {
      System.Out.Println("key :"+mapData.getKey() + " " + 
        " value : " +mapData.getValue());
    });
  }
});
return new ModelAndView("redirect:/home");

}

0
user

Castez votre réponse DB de findAll vers une liste de types d'objets, comme (List of Sometype), puis renvoyez les données. Cela résoudra votre problème.

0
abolfazl rostamian