Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonView和统一封装返回结果的问题 #53

Closed
yangwenliang123 opened this issue Jul 31, 2023 · 3 comments
Closed

JsonView和统一封装返回结果的问题 #53

yangwenliang123 opened this issue Jul 31, 2023 · 3 comments

Comments

@yangwenliang123
Copy link

项目里很多时候使用统一封装返回结果,例如net.dreamlu.mica.core.result.R类。

public class User {
public interface UserInfo{};
public interface UserDetail extends UserInfo{};

private String username;
private String password;
@JSONVIEW(UserInfo.class)
public String getUsername() {
return username;
}
@JSONVIEW(UserDetail.class)
public String getPassword() {
return password;
}
}

@RequestMapping("/user")
@JSONVIEW(User.UserInfo.class)
public User getUser(@RequestParam String username){
User user = new User();
user.setUsername("123");
user.setPassword("123");
return user;
}

@RequestMapping("/user")
@JSONVIEW(User.UserInfo.class)
public R getUser(@RequestParam String username){
User user = new User();
user.setUsername("123");
user.setPassword("123");
return R.success(user);
}

在第一个返回中 可以只给前端展示username属性

但是在第二个返回中 用R包装了User对象后,JsonView就失效了,在前端无法获取到User对象的数据。

@MessiCY1994
Copy link

MessiCY1994 commented Jul 31, 2023 via email

@ChunMengLu
Copy link
Member

@yangwenliang123 这个是 chatgpt 的回答,你试试,可以微调,做的更加完美:

当响应统一包装为Result<User>时,@JsonView注解无法直接生效。这是因为@JsonView注解的作用对象是属性字段,而不是包装类。

为了使@JsonView注解生效,你可以通过下面方式来处理:

使用ResponseBodyAdvice:实现ResponseBodyAdvice接口,将@JsonView注解的配置应用到返回结果上。

@ControllerAdvice
public class JsonViewResponseBodyAdvice implements ResponseBodyAdvice<Object> {
    
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }
    
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
            Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
            ServerHttpResponse response) {

        if (body instanceof Result<?>) {
            R<?> result = (Result<?>) body;
            if (result.getData() != null && result.getData() instanceof User) {
                User user = (User) result.getData();
                MappingJacksonValue wrapper = new MappingJacksonValue(user);
                wrapper.setSerializationView(UserViews.Full.class);
                return new Result<>(result.getCode(), result.getMessage(), wrapper);
            }
        }
        
        return body;
    }
}

上面的代码中,JsonViewResponseBodyAdvice类实现了ResponseBodyAdvice接口,并在beforeBodyWrite方法中对返回结果进行处理。如果返回结果是Result<User>类型且包含非空的User对象,则将User对象进行包装,并设置视图为UserViews.Full.class

@ChunMengLu
Copy link
Member

ChunMengLu commented Aug 24, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants