简体   繁体   English

将JSON作为响应Spring Boot返回

[英]Returning JSON as Response Spring Boot

I am trying to get rest response as json instead I am getting as string. 我试图得到休息响应作为json而不是我得到字符串。

Controller 调节器

@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();
}

Repository 知识库

public interface SomeRepo extends CrudRepository<SomeModel,Integer>{

}

Models 楷模

@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
}

when I run localhost:8080/api/getsome I am getting: 当我运行localhost时:8080 / api / getsome我得到:

[
 {
    "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" }]}"
  }
]

Field t_col is returning string instead of json. 字段t_col返回字符串而不是json。 How do I get json objects in response? 如何获取响应的json对象?

As for the database, the three columns are int, varchar and varchar. 对于数据库,三列是int,varchar和varchar。

Any help would be appreciated. 任何帮助,将不胜感激。 Thanks !! 谢谢 !!

In your controller add json response: 在你的控制器中添加json响应:

 @RequestMapping(value = "/getsome", method = RequestMethod.GET, produces = "application/json"

And wrap the getData string as response 并将getData字符串包装为响应

    public class StringResponse {

        private String response;

        public StringResponse(String s) { 
           this.response = s;
        }

}

Change your some model class like this 像这样改变你的一些模型类

@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

    @Column(name = "t_col", columnDefinition = "json")
    @Convert(attributeName = "data", converter = JsonConverter.class)
    private Map<String, Object> json = new HashMap<>();

    //constructors
    //getters and setters
}

Write a json converter class. 写一个json转换器类。

@Converter
public class JsonConverter
                    implements AttributeConverter<String, Map<String, Object>> 
{


    @Override
    public Map<String, Object> convertToDatabaseColumn(String attribute)
    {
        if (attribute == null) {
           return new HashMap<>();
        }
        try
        {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(attribute, HashMap.class);
        }
        catch (IOException e) {
        }
        return new HashMap<>();
    }

    @Override
    public String convertToEntityAttribute(Map<String, Object> dbData)
    {
        try
        {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(dbData);
        }
        catch (JsonProcessingException e)
        {
            return null;
        }
    }
}

It will convert database json attribute to your desire results. 它会将数据库json属性转换为您想要的结果。 Thanks 谢谢

You need to define your json attribute as JsonNode so jackson can read it back and forrward, but mark is as @Transient so JPA does not try to store it on database. 您需要将json属性定义为JsonNode,以便jackson可以将其读回和转发,但标记为@Transient因此JPA不会尝试将其存储在数据库中。

Then you can code getter/setter for JPA, where you translate from JsonNode to String back and forward. 然后你可以为JPA编写getter / setter代码,你可以在这里从JsonNode转换为String。 You define a getter getJsonString that translate JsonNode json to String . 您定义了一个getter getJsonStringJsonNode json转换为String That one can be mapped to a table column, like 'json_string', then you define a setter where you receive the String from JPA and parse it to JsonNode that will be avaialable for jackson, jackson then will translate it to a json object not a string as you mention. 那个可以映射到表列,比如'json_string',然后你定义一个setter,你从JPA接收String并将其解析为jsonNode,这将是jackson的可用,然后jackson将它转换为json对象而不是你提到的字符串。

@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();
    }
  }
}

Notice, @Column are defined at gettters because we need to indicate JPA to use getJsonString and JPA requires consistency so all column's getters must be mark with @Columns . 注意, @Column column是在gettters中定义的,因为我们需要指示JPA使用getJsonString并且JPA需要一致性所以所有列的getter必须用@Columns标记。

  @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");

} }

Cast your DB answer from findAll to a list of object type, like (List of Sometype), then return data. 将您的数据库答案从findAll转换为对象类型列表,如(Sometype类型列表),然后返回数据。 This will be resolve your problem. 这将解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM