[英]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.