[英]Spring throw CustomObject to JSON in controller
我想根据控制器内部的某些逻辑返回/抛出一个对象。
例如,假设需要用户登录的内容我想返回一条适当的消息
throw a new ReturnLoginMessage("Must login", "xx@xx.com", 111)
我不能只抛出ReturnLoginMessage,因为它只会返回以下内容:
"exception": "com.userapi.returntypes.ReturnLoginMessage"
这根本没有用! 我想要该returnloginmessage对象的JSON表示形式。
{
"message": "Must login",
"email": "xx@xx.com",
"code": "111"
}
给定以下控制器是否可行? 该控制器的作用是检查用户是否已经存在,如果存在,则必须登录 (这就是为什么我返回returnloginmessage对象的原因。
@RequestMapping(value="login/email", method=RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE })
UserCredential login(@RequestBody UserFacebookLoginContext body) throws IOException, InvalidKeySpecException,
NoSuchAlgorithmException, ConfirmLogin, ClassNotFoundException, ConfirmResponse, InvalidRequestException, ConfirmLoginEmail {
... Logic that checks to see if user exists....
if (user does exist)
throw new ReturnLoginMessage("Must login", "xx@xx.com", 111); // THis returns "exception": "com.userapi.returntypes.ReturnLoginMessage"
else if(other condition)
throw new OtherMessage("...", "...");
else
return UserCredential;
是否可以返回ReturnLoginMessage的JSON表示形式 ? 给定以下Java对象?
public class ReturnLoginMessage extends Exception {
private int code;
private String message;
private String email;
private Date timestamp;
public ReturnLoginMessage(int code, String message) {
this.code = code;
this.email = email;
this.timestamp = new Date();
}
public ReturnLoginMessage(String message, int code, String email) {
super(message);
this.code = code;
this.email = email;
this.timestamp = new Date();
}
... Getters .... Setters ...
}
我通过这种方式实现了几乎相同的事情(也许)
第一
在您的REST控制器上添加ExceptionHandler,然后将您的异常作为JSON返回(使用@ResponseBody)。
@Controller
@RequestMapping("/rest")
public class RestfulTodoController {
@ExceptionHandler(ReturnLoginMessage.class)
@ResponseBody
public ReturnLoginMessage handleException(final ReturnLoginMessage e) {
return e;
}
// and your login handler method
}
在扩展AbstractMappingJacksonResponseBodyAdvice的通知中检查响应是否为Json,返回类型是否为ReturnLoginMessage,如果响应为ReturnLoginMessage,则根据需要修改响应
@ControllerAdvice
public class MyResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice {
@Override
public boolean supports(final MethodParameter returnType,
final Class<? extends HttpMessageConverter<?>> converterType) {
return super.supports(returnType, converterType)
&& null != returnType.getMethodAnnotation(ResponseBody.class);
}
@Override
protected void beforeBodyWriteInternal(final MappingJacksonValue bodyContainer, final MediaType contentType,
final MethodParameter returnType, final ServerHttpRequest request, final ServerHttpResponse response) {
if (bodyContainer.getValue() instanceof ReturnLoginMessage) {
//set some object as you like
bodyContainer.setValue();
}
}
}
}
最后
在您的建议上方注册为Bean
@Configuration
public class WebAppConfiguration {
@Bean
public MyResponseBodyAdvice myResponseBodyAdvice() {
return new MyResponseBodyAdvice();
}
}
使用Fasterxml Jackson库Java最佳JSON解析器
Fasterxml Jackson将Java Collection直接转换为JSON。
Maven依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${faster-xml-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${faster-xml-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${faster-xml-version}</version>
</dependency>
控制器代码
@RequestMapping(value="login/email", method=RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
Map<String, Object> login(@RequestBody UserFacebookLoginContext body) throws IOException, InvalidKeySpecException,
NoSuchAlgorithmException, ConfirmLogin,
ClassNotFoundException, ConfirmResponse, InvalidRequestException,
ConfirmLoginEmail {
... Logic that checks to see if user exists....
if (user does exist)
return Utility.getSuccessResponse("message","Must
login","email","xx@xx.com","code",111);
else if(other condition)
return Utility.getSuccessResponse("", "");
else
return Utility.getSuccessResponse("userCredential", UserCredential);
实用类
public class Utility {
public static Map<String, Object> getSuccessResponse(Object... responseContent) {
if (responseContent.length % 2 != 0) {
throw new IllegalArgumentException();
}
Map<String, Object> responseObject = new HashMap<String, Object>();
Map<String, Object> responseList = new HashMap<String, Object>();
for (int i = 0; i < responseContent.length; i = i + 2) {
responseList.put(responseContent[i].toString(), responseContent[i + 1]);
}
responseObject.put("result", responseList);
return responseObject;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.