从 Spring 控制器方法发送 Json 响应的最佳实践
Posted
技术标签:
【中文标题】从 Spring 控制器方法发送 Json 响应的最佳实践【英文标题】:Best practice to send Json response from Spring controller methods 【发布时间】:2017-11-22 18:14:31 【问题描述】:我想从 spring 控制器返回一个字符串(json 字符串)作为对它接收到的 AJAX 调用的响应,根据我是否提交了 @Valid 表单,响应可能会有所不同。这就是我处理它的方式,并想知道这是否被认为是最佳实践? 请注意我正在使用@RestController,所以@ResonseBody 应用所有方法。
@RequestMapping(value = "/save" , method = RequestMethod.POST)
public String saveScheduledAlert(@Valid ScheduledAlertForm scheduledAlertForm, BindingResult bindingResult)
StringBuilder jsonString = new StringBuilder();
if(bindingResult.hasErrors())
jsonString.append("\"success\" : \"false\"");
for(ObjectError error : bindingResult.getAllErrors())
jsonString.append(",\"").append(((FieldError) error).getField()).append("\":\"").append(error.getDefaultMessage()).append("\"");
else
//save the data
jsonString.append("\"success\" : \"true\"");
jsonString.append("");
return jsonString.toString();
【问题讨论】:
@ResponseBody 注释? - ***.com/questions/28646332/… 我正在使用 @RestController 它是一个 Spring Boot 应用程序 【参考方案1】:老问题,但对于其他需要帮助的人,我为此使用了自定义 ApiResponse
类。我的班级是这样的:
public class ApiResponse<T>
String message;
int statusCode;
T data
//....getters and setters
这样,我可以使用“SUCCESS”或“ERROR”作为消息,适当的HttpStatus
代码,然后任何类型作为我要发送的数据。
然后,在控制器中,我只是这样做:
@PostMapping("/sign-up")
public ResponseEntity<String> signUp(@RequestBody Account account)
if (accountService.getAccountByEmail(account.getEmail()) != null)
ApiResponse<String> apiResponse = new ApiResponse<>("A user with that email
already exist", HttpStatus.CONFLICT.value(), null);
return new ResponseEntity<String>(new Gson().toJson(apiResponse), HttpStatus.CONFLICT);
// ... rest of controller code
如您所见,我使用 Gson
依赖项来创建我的 JSON 字符串。
【讨论】:
【参考方案2】:所以基本上你想要做的是生成 2 个 pojos
public class RestWrapperDTO
protected boolean success;
public boolean isSuccess()
return success;
public void setSuccess(boolean value)
success = value
还有另一个错误 DTO
public class RestErrorDTO extends RestWrapperDTO
private Map<String, String> errors;
public Map<String, String> getErrors()
return errors;
public void setErrors(Map<String, String> value)
errors = value
和你的控制器
@RequestMapping(value = "/save" , method = RequestMethod.POST)
public RestWrapperDTO saveScheduledAlert(@Valid ScheduledAlertForm scheduledAlertForm, BindingResult bindingResult)
StringBuilder jsonString = new StringBuilder();
if(bindingResult.hasErrors())
RestErrorDTO errorDTO = new RestErrorDTO();
// fill map with errors here
return errorDTO;
else
RestWrapperDTO wrapperDTO = new RestWrapperDTO();
wrapperDTO.setSuccess(true);
return wrapperDTO;
这不是最充分的代码,但它应该可以帮助你:D
如果你使用简单的@Controller 注解——你是什么 寻找的是
@ResponseBody
-annotation或者如果你使用@RestController 而不是它已经可用
你可以简单地返回一个带有 Serializable 接口的对象——一个 简单的 POJO 和 spring 将处理其余部分。
进一步阅读:
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-responsebody How exactly works the Spring @ResponseBody annotation in this RESTful application example? 对于@RestController 的小解释Difference between spring @Controller and @RestController annotation
【讨论】:
我已经将 ResonseBody 应用于所有方法,因为我正在使用@RestController,此外,我想要做的只是返回成功:如果一切顺利,则返回 true 或发送成功:false,然后验证错误作为 json 中的键值对仅此而已。 基本上我有解释和@nick savenia 代码示例 我的建议, 我之前想过 return Object 但想知道如何发送成功 : false 消息以在客户端发现出现问题? 谢谢,这是有道理的,但为什么我不应该只使用一个带有布尔标志和 Map 的类来处理错误呢?这还不够简单吗?【参考方案3】:创建一个 POJO,如下所示:
public class SuccessPOJO
private String success;
.....
getters and setters
.....
现在您可以设置成功消息的值并返回此SuccessPOJO
对象。在浏览器中,您将收到带有成功消息的JSON
格式化对象!
【讨论】:
是的,但我也想发送数量可变的验证错误,我该如何发送?以上是关于从 Spring 控制器方法发送 Json 响应的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
从 Spring Boot 控制器返回非 JSON 数据(对象列表)
如何将 json 数据从我的 jsp 页面发送到 spring rest 控制器
如何在 Javascript 中从 Spring 获取 JSON 响应
使用 JSON Sanitizer 清理来自 Spring MVC 控制器的响应 JSON?