java的long類型轉為json格式后,js中精度丟失問題


環境:

使用spring mvc 配置json消息轉換器為MappingJackson2HttpMessageConverter

發現long類型的數據到了js端會丟失精度

解決方案:

將long統一轉為string類型

方法一:

數據層轉換,由於項目使用了spring 的jdbc模版類,查詢時調用了spring的query方法

    public <T> List<T> query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
            throws DataAccessException {

        return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rowMapper);
    }

這個方法有個參數rowMapper,我用來將數據庫數據轉換為Map,我通過自定義實現RowMapper接口,將mysql數據庫里的bigint類型轉為string而不是默認的long,代碼如下:

public class HashMapRowMapper implements RowMapper<Map<String, Object>> {

    @Override
    public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        Map<String, Object> mapOfColValues = new LinkedCaseInsensitiveMap<Object>(columnCount);
        for (int i = 1; i <= columnCount; i++) {
            String key = JdbcUtils.lookupColumnName(rsmd, i);
            Object obj = JdbcUtils.getResultSetValue(rs, i);
            if (obj == null) {
                mapOfColValues.put(key, obj);
            }
            if (obj != null) {
                Class<?> cc = obj.getClass();
                if (cc.getName().equals("java.math.BigInteger") && obj != null) {
                    mapOfColValues.put(key, String.valueOf(obj));
                } else {
                    mapOfColValues.put(key, obj);
                }
            }
        }
        return mapOfColValues;
    }

}

調用代碼如下,注意query傳入的最后一個參數使用了自定已類HashMapRowMapper:

    public Map<String, Object> getItem(Map<String, Object> inParam) {
        if (MapUtil.getValue("id", inParam) == "")
            throw new InParamCheckException("id不能為空:" + inParam.get("id"));
        String orgId = MapUtil.getValue("org_id", inParam);
        String appId = IDConstants.APP_ID_PIS;
        NamedParameterJdbcTemplate jdbc = jdbcRouteHelper.getJDBCTemplate(orgId, appId);

        return new MyMap().put("simple_info", jdbc.query("select * from simple_info where id=:id", inParam, new HashMapRowMapper()))
                .put("simple_test",
                        jdbc.query("select * from simple_test where simple_info_id=:id", inParam, new HashMapRowMapper()))
                .getMap();
    }

 

 

方法二:

配置spring的消息轉換器的ObjectMapper為自定義的類

配置如下:

    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean
                    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                        <bean class="LongToStringJsonConverter">
                            <property name="supportedMediaTypes">
                                <list>
                                    <value>application/json;charset=UTF-8</value>
                                    <value>text/html;charset=UTF-8</value>
                                    <value>text/plain;charset=UTF-8</value>
                                </list>
                            </property>
                            <property name="dateFormat">
                                <bean class="java.text.SimpleDateFormat">
                                    <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
                                </bean>
                            </property>
                        </bean>
                    </property>
                </bean>
    </bean>

其中LongToStringJsonConverter為自定義轉換器

public class LongToStringJsonConverter extends ObjectMapper {
    /**
     * 
     */
    private static final long serialVersionUID = 1683531771040674386L;

    @Override
    public ObjectMapper registerModule(Module module) {
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        return super.registerModule(simpleModule);
    }
}

spring中controller層的代碼使用時無需特別修改,下面是一個controller類里返回json數據,代碼不做任何修改,long類型已經轉為string返回到web瀏覽器了.

    @RequestMapping("/")
    @ResponseBody
    public Map<String, Object> init() {
        List<Object> lstDoctor = dictConsumer.getBaseParam().getItemsFromCache(cache_keys.PIS_doctor.name(),
                test_org_id, IDConstants.APP_ID_PIS);
        List<Object> lstSubjectType = dictConsumer.getBaseParam().getItemsFromCache(cache_keys.PIS_subject_type.name(),
                test_org_id, IDConstants.APP_ID_PIS);
        List<Object> lstTest = dictConsumer.getBaseParam().getItemsFromCache(cache_keys.PIS_test.name(),
                test_org_id, IDConstants.APP_ID_PIS);        
        MyMap map = new MyMap();
        map.put("doctors", lstDoctor).put("subject_types", lstSubjectType).put("tests", lstTest);
        return map.getMap();

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM