返回 JSON 作为响应 Spring Boot
Posted
技术标签:
【中文标题】返回 JSON 作为响应 Spring Boot【英文标题】:Returning JSON as Response Spring Boot 【发布时间】:2019-07-27 14:31:29 【问题描述】:我正在尝试以 json 形式获取休息响应,而不是以字符串形式获取。
控制器
@RestController
@RequestMapping("/api/")
public class someController
@Autowired
private SomeService someService;
@GetMapping("/getsome")
public Iterable<SomeModel> getData()
return someService.getData();
服务
@Autowired
private SomeRepo someRepo;
public Iterable<someModel> getData()
return someRepo.findAll();
存储库
public interface SomeRepo extends CrudRepository<SomeModel,Integer>
模型
@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
当我运行 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" ]"
]
字段 t_col 正在返回字符串而不是 json。如何获取 json 对象作为响应?
对于数据库,三列分别是int、varchar和varchar。
任何帮助将不胜感激。谢谢!!
【问题讨论】:
您必须管理从其余端点接收到的 json 到您将其存储在数据库中的字符串字段的转换。 Couriosuly 我几天前在下一个问题***.com/questions/54975002/… 中回答了同样的问题 【参考方案1】:将您的 DB 答案从 findAll
转换为对象类型列表,例如 (List of Sometype),然后返回数据。这将解决您的问题。
【讨论】:
【参考方案2】:像这样改变你的一些模型类
@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
编写一个 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;
它将数据库 json 属性转换为您想要的结果。谢谢
【讨论】:
【参考方案3】:您需要将您的 json 属性定义为 JsonNode,以便 jackson 可以将其读取并转发,但标记为 @Transient
,因此 JPA 不会尝试将其存储在数据库中。
然后您可以为 JPA 编写 getter/setter 代码,您可以在其中从 JsonNode 来回转换为 String。您定义了一个 getter getJsonString
将 JsonNode json
转换为 String
。那个可以映射到一个表列,比如'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();
注意,@Column
是在 gettter 中定义的,因为我们需要指示 JPA 使用 getJsonString
,而 JPA 需要一致性,因此所有列的 getter 都必须用 @Columns
标记。
【讨论】:
谢谢,它对我有用!如果我需要将 json 输入作为字符串保存在数据库中,它是如何工作的? 该部分已包含在解决方案中,您会看到当 JPA 尝试将 POJO 转换为插入语句时,它将执行getJsonString
方法,因为它标记为 @Column
like to jsonString
专栏。所以只要你有这样的 json/jsonString getter/setter,它就会像你预期的那样工作。
我尝试了各种方法使用 JsonNode 将原始 Json 对象保存到字符串,但无法正常工作。我收到以下错误“状态”:400、“错误”:“错误请求”、“消息”:“JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList
的实例;嵌套异常是 com.fasterxml.jackson。 databind.exc.MismatchedInputException: 无法在 [Source: (PushbackInputStream); line: 1, column: 1]", "trace": "org.springframework.http.converter. HttpMessageNotReadableException:JSON 解析 e
您需要更具体地了解您正在尝试制作的实现,在您提供的示例中,没有包含数组的元素。
对于 POST 映射,我提供以下控制器:@PostMapping("/saverawjson") public void saveRawJson(@RequestBody SomeModel someModel) //..... someRepository.save(someModel)我正在使用以下回购公共接口 SomeRepo extends CrudRepository @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");
【讨论】:
【参考方案5】:在您的控制器中添加 json 响应:
@RequestMapping(value = "/getsome", method = RequestMethod.GET, produces = "application/json"
并将 getData 字符串包装为响应
public class StringResponse
private String response;
public StringResponse(String s)
this.response = s;
【讨论】:
有趣的快速修复,但在调用我的 API 时出现错误 406。它到底在等什么?以上是关于返回 JSON 作为响应 Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章
SpringDoc (spring boot) utf-8 json 标头响应文档
Spring boot @ExceptionHandler 将响应返回为 html