[alibaba/fastjson]JSONField偶尔失效

2025-10-28 754 views
2

各位大神您好,这个问题困扰几天了一直没找到办法。

就是A服务上面我定义了一个ModelVO 里面加了 @JSONField(name="序列号")等,希望的是 最终结果如下(对应的json属性变成中文),但是会发现偶尔是中文 偶尔是英文,然后发现一个规律。如果json解析发现这个对象是linkedHashMap的时候 就是英文,如果是发现是ModelVo的时候就是中文(实际上我这个A服务的确每次都代码里面存进去的都是VO实体对象),麻烦有知道的看看怎么解决,我放在vo的属性文件也不行 放在get也是一样。

{ "data": { "产品类型": "iPhone6,2", "产地": "iPhone 5s", "序列号": "DX6R5VW1FR9M", "支持网络": [ "https://www.apple.com/iphone/LTE/", "https://support.apple.com/HT202909" ], "网络型号,若与本机不一致,则可能为翻新机": "A1530" }, "errorCode": "", "errorMsg": "", "success": true }

package com.fastboot.fmd.checkcoverage.api.vo.apple;

import com.alibaba.fastjson.annotation.JSONField; import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.io.Serializable;

/**

  • @description:
  • @author: mj
  • @createDate: 2019/6/20 12:30 AM
  • @projectName: fmd-checkcoverage
  • @package: com.fastboot.fmd.checkcoverage.api.vo */ @JsonIgnoreProperties(ignoreUnknown = true) public class ModelVO implements Serializable {

    private static final long serialVersionUID = -2555435029325937287L; /**

    • 序列号 */

    private String sn; /**

    • 产品 */ private String product; /**
    • 网络型号,若与本机不一致,则可能为翻新机 */ private String model; /**
    • 产品类型 */ private String identifier; /**
    • 支持网络 */ private String[] network;

    @JSONField(name="序列号") public String getSn() { return sn; }

    public void setSn(String sn) { this.sn = sn; }

    @JSONField(name="产地") public String getProduct() { return product; }

    public void setProduct(String product) { this.product = product; }

    @JSONField(name="网络型号,若与本机不一致,则可能为翻新机")

    public String getModel() { return model; }

    public void setModel(String model) { this.model = model; }

    @JSONField(name="产品类型") public String getIdentifier() { return identifier; }

    public void setIdentifier(String identifier) { this.identifier = identifier; }

    @JSONField(name="支持网络") public String[] getNetwork() { return network; }

    public void setNetwork(String[] network) { this.network = network; } }

回答

9

可以提供下序列化/反序列化部分使用的函数代码吗 :)

5
  1.     //todo 这里存的vo。 当初最开始用的fastjson 但是发现因为加了jsonfild中文导致有问题 所以变相先用jackson反序列化为 VO.然后将VO对象存入 response这个结果集里面。打印这个vo对象是中文。

注意:这里是一个RPC远程服务。A 调用这个服务 返回response ,然后A那边对应有一个ResponseBodyAdvice会判断如果返回值是response则 bodyRewrite = JSONObject.toJSONString(body); 序列化,但是打印 logger.info("ResponseRewriteAdvice into Response class[{}]", object == null ? "" : object.getClass().toString()); 会发现 有时候是linkedHashMap 有时候是vo。但是服务那边打印的都是vo。

反序列化: @Override public Response serial(CommonReqParamDTO commonReqParamDTO) { Response response = new Response<>(); Map<String, String> params = new HashMap<>(1); Map<String, String> headers = new HashMap<>(1); initReqParamMap(params, headers, commonReqParamDTO); ObjectMapper objectMapper = new ObjectMapper(); StringBuffer urlBuffer = new StringBuffer(baseConfig.getFmdService().get("url")).append(Constant.ServiceCodeUrl.SERIAL.getUrl()); Response result = HttpClientUtils.doGet(urlBuffer.toString(), headers, params,Constant.CONNECT_TIMEOUT,Constant.SOCKET_TIMEOUT); if (result.isSuccess() && isSuc(result)) { ImeiVO imeiVO = objectMapper.readValue(result.getData(), ImeiVO.class); //todo 这里存的vo。 当初最开始用的fastjson 但是发现因为加了jsonfild中文导致有问题 所以变相先用jackson反序列化为 VO.然后将VO对象存入 response这个结果集里面。 response.setDataWithSuccess(imeiVO); } else { setErrorCodeWithMsg(response, objectMapper, result); }

//这里一定打印出来的都是中文 但是RPC结果解析有时候是英文有时候中文 logger.info("serial response[{}]", JSONObject.toJSONString(response));

    return response;
}

序列化: 序列化的时候 有时候是linkedHashMap 如果是这个则返回给前端的(打印的也是)都是英文。如果是vo则是中文。

8

可以提供下序列化/反序列化部分使用的函数代码吗 :)

我已经发你了 麻烦看看 A 网关,他会面向APP,都是返回的response对象。response里面可以存放实体。 然后 A 请求 B服务(RPC 用的dubbo)。 B服务将对象存入到response里面 返回【打印的时候可以看到 json对象都是中文正常 class也是对应的vo],在A中 会发现 有时候是map(map则失效显示的是非中文),vo则正常。谢谢 详细代码看我发的

如下是序列化的地方:

public class ResponseRewriteAdvice implements ResponseBodyAdvice { private static Logger logger = LoggerFactory.getLogger(ResponseRewriteAdvice.class); private static final String DATA_REMAKE = "##$$##"; private static final String DATA_REMAKE_REPLACE = "\"##$$##\"";

public ResponseRewriteAdvice() {
}

public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    return true;
}

public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    response.setStatusCode(HttpStatus.OK);
    if (selectedContentType != null && "application".equalsIgnoreCase(selectedContentType.getType()) && "json".equalsIgnoreCase(selectedContentType.getSubtype())) {
        response.getHeaders().setContentType(MediaType.parseMediaType("text/json;charset=utf-8"));
    } else {
        response.getHeaders().setContentType(selectedContentType);
    }

    logger.info("ResponseRewriteAdvice into body[{}],class[{}]", JSONObject.toJSONString(body));
    String bodyRewrite;
    if (body instanceof Response) {
        Object object = ((Response)body).getData();
        logger.info("ResponseRewriteAdvice into Response class[{}]", object == null ? "" : object.getClass().toString());
        bodyRewrite = JSONObject.toJSONString(body);

看起来你的问题是,有时候被反序列化成map了

看起来你的问题是,有时候被反序列化成map了

是 有时候是map 这个请问你知道原因吗?

你好,请问你用的是哪个版本的fastjson

你好,请问你用的是哪个版本的fastjson

1.2.61

你好,请问你用的是哪个版本的fastjson

1.2.61

你好,你的目的是需要序列化和反序列化都是中文属性吗,如果是的你尝试将@JSONField同时加在get/set方法上试试看。也可以直接加在属性上。加上之后反序列化还是用fastJSON。

1

看起来你的问题是,有时候被反序列化成map了

0

看起来你的问题是,有时候被反序列化成map了

是 有时候是map 这个请问你知道原因吗?

0

你好,请问你用的是哪个版本的fastjson

8

你好,请问你用的是哪个版本的fastjson

1.2.61

5

你好,请问你用的是哪个版本的fastjson

1.2.61

你好,你的目的是需要序列化和反序列化都是中文属性吗,如果是的你尝试将@JSONField同时加在get/set方法上试试看。也可以直接加在属性上。加上之后反序列化还是用fastJSON。