zoukankan      html  css  js  c++  java
  • 存在日期类型的JSON数据,进行SpringMVC参数绑定时存在的问题和解决方案

    这篇文章已经过时了。

    请参考比较合适的前后端交互方式

    首先是发送AJAX请求的html页面

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>AJAX</title>
    <script type="text/javascript" src="/lib/jquery-3.2.1.min.js"></script>
    <script type="text/javascript">
        var saveData = {"en":"sss",
            "ch":"げ啊爲",
            "dt":"2012-01-02 03:04:05",
            "no":"-3.1415926"};
    
        function json_obj() {
            $.ajax({
                type:"post",
                url:"/ajax/json_obj",
                dataType:"json",
                data:saveData,
                success:function(data) {
                    alert(data);
                },
                error:function(data) {
                    alert('error');
                }
            });
        }
    
        function json_str() {
            $.ajax({
                type:"post",
                url:"/ajax/json_str",
                dataType:"json",
                contentType : 'application/json',
                data:JSON.stringify(saveData),
                success:function(data) {
                    alert(data);
                },
                error:function(data) {
                    alert('error');
                }
            });
        }
    </script>
    </head>
    <body>
        <input id="a" value="b" type="hidden" />
        <button onclick="json_obj()">json_obj</button><br><br>
        <button onclick="json_str()">json_str</button><br><br>
    </body>
    </html>

    然后是控制器和用于和参数绑定的实体类

    /** 'package' and 'import' ingore */
    
    @Controller
    @RequestMapping("ajax")
    public class AjaxController {
    
        private static final Logger log = LogManager.getLogger(AjaxController.class);
    
        @RequestMapping(value = "json_obj")
        @ResponseBody
        public String jsonobj(Data data) {
            log.info("请求开始");
            log.info("请求成功");
            return "success";
        }
    
        @RequestMapping(value = "json_str")
        @ResponseBody
        public String jsonstr(@RequestBody DataS data) {
            log.info("请求开始");
            log.info("请求成功");
            return "success";
        }
    
    }
    
    class Data {
    
        private String en;
        private String ch;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date dt; private Double no; /** getter and setter ignore */ } class DataS { private String en; private String ch; private String dt; private String no; /** getter and setter ignore */ }

    以上的例子中,无论把json_obj和json_str的ajax.type改成get还是post,都是能成功运行得到正确结果的。

    JS函数   <->   控制器的请求方法(实体类) 

    json_obj   <->   jsonobj(Data)

    这种情况下,ajax.data的内容是一个json对象,没有经过JSON.stringify()的转换。

    尽量不要指定json_obj的ajax为contentType="application/json",否则,

    对于get请求没关系,对于post请求,jsonobj(Data)的参数data无法得到绑定,会是null

    jsonobj(Data)的参数前不能指定@RequestParam,

    因为无论是post还是get请求,请求中都没有一个名为"data"的请求参数。

    jsonobj(Data)的参数前不能指定@RequestBody,否则HTTP-400

    发送一个json对象的好处是,实体类Data的域的类型可以指定为具体的类型,比如Double和Date。

    其中Date域需要指定@DataTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")

    注解里的pattern最好跟ajax发送的日期一致,

    如果pattern的信息比ajax少时,会丧失时间精度,

    如果pattern的信息比ajax多是,Date域无法得到绑定,会是null

    json_str   <->   jsonstr(DataS)

    这种情况下,ajax.data的内容是一个json字符串,经过JSON.stringify()的转换。

    ajax必须指定contentType : 'application/json',否则HTTP-415,

    jsonobj(Data)的参数前必须指定@RequestBody,否则jsonobj(Data)的参数data无法得到绑定,会是null

    发送一个json字符串的好处是,不需要进行类型转换了,实体类DataS的域都是String类型,

    (这可能也是他的坏处,如果有需求的话,需要专门把String 转换成其他类型)

    另一个好处是在数据验证方面,由于JSR303的@Pattern只支持String域,DataS的所有域都可以进行正则验证,保证了后续类型转化的安全性

    向前端返回存在Date字段的数据的解决方法

    处理Ajax请求的请求方法,几乎都会有@ResponseBody,请求的方法的返回值一般会有两种情况。

    • 返回一个String

    这种情况,一般会做一步new ObjectMapper.writeValueAsString(resultEntity);的处理,

    如果resultEntity里面有Date域,那直接用ObjectMapper转化的话,Date域会被转换成一串莫名其妙的数字,

    为了避免这个现象,需要在ObjectMapper对象里注入一个转换器。

            ObjectMapper om = new ObjectMapper();
            om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            String s = om.writeValueAsString(resultEntity);
                
            return s;    
    • 返回一个实体类

    这种情况,如果实体类都是String域,那肯定没问题,

    如果实体类里有Date域,那么前端ajax.success函数里面直接data.dt会被转换成以串莫名其妙的数字,

    这种情况下的,这个现象,后端是无法解决的。

    以上两点中,出现“一串莫名其妙的数字”的情况,前端是有办法解决的。

        function timeStamp2String(time){
            var datetime = new Date();
            datetime.setTime(time);
            var year = datetime.getFullYear();
            var month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
            var date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
            var hour = datetime.getHours()< 10 ? "0" + datetime.getHours() : datetime.getHours();
            var minute = datetime.getMinutes()< 10 ? "0" + datetime.getMinutes() : datetime.getMinutes(); 
            var second = datetime.getSeconds()< 10 ? "0" + datetime.getSeconds() : datetime.getSeconds();
            return year + "-" + month + "-" + date+" "+hour+":"+minute+":"+second;
        }

    简单来说就是在JS里面引入一个Date对象。

  • 相关阅读:
    前端日期格式化
    前端显示省略号
    模糊搜索和时间区间搜索
    数字保持小数点后一位
    每天一个linux命令(tcpreplay)
    每天一个linux命令(find)
    每天一个linux命令(netstat)
    每天一个linux命令(lsof)
    每天一个linux命令(tcpdump)
    每天一个linux命令(route)
  • 原文地址:https://www.cnblogs.com/deolin/p/7248763.html
Copyright © 2011-2022 走看看