繁体   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