簡體   English   中英

Spring將CustomObject扔到控制器中的JSON

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

您可以通過為ReturnLoginMessage.class聲明新的ExceptionHandler方法來ReturnLoginMessage.class 看到這個答案。

另一種方法是將login的返回值擴展到更通用的名稱。 例如:

  1. 聲明它返回Object而不是UserCredentials ,只返回ReturnLoginMessage而不是將其拋出。

  2. 聲明它返回Map<String,Object>並為兩種情況構造適當的鍵/值對。 看到這個答案

我通過這種方式實現了幾乎相同的事情(也許)

第一

在您的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM