【问题标题】:Spring: passing data between server and client (Java objects to JS objects)Spring:在服务器和客户端之间传递数据(Java对象到JS对象)
【发布时间】:2012-04-23 08:48:09
【问题描述】:

我想在我的服务器(使用 Spring)和客户端(在 ExtJS 中)之间实现透明数据传递。

在服务器端,我有 Spring 控制器返回 ModelAndView 对象(使用 JSP)。我通常不创建模型对象,我只是将项目放入模型 Map 中。

我想要简单透明的 Java 到 Javascript 对象转换。在服务器端,我将一个 Java Date 对象放入地图中,然后在客户端上得到一个 Javascript Date 对象。 IE。在服务器上我写了这样的代码:

public ModelAndView getModelAndView(User user) {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    modelMap.put("date", new Date());
    modelMap.put("intarray", new int[] {1,2,3});
    return new ModelAndView("mainpage", modelMap);
}

在客户端我用 JSP 编写:

var model = <someMagicTagOrSomething />

在呈现的 HTML 中我得到:

var model = {
     date: Date.parse('2012-01-01 12:12:12', 'Y-m-d H:m:s'), //JS Date object
     intarray: [1,2,3]
}

我在 Spring 文档中看到的大部分内容都涉及使用 @NumberFormat(style=Style.PERCENT) 之类的注释在服务器上指定对象格式,然后使用 form:input 标记在客户端上获取它们。这不是我想要的,因为我想在客户端格式化日期,而不用担心它们以什么格式传输给客户端。

完成此任务的最佳方法是什么?是否有开箱即用的解决方案,还是我需要自己写一些东西?我知道我可以使用像 Gson 这样的库将我的模型转换为 JSON,但这会将 Java 日期作为字符串返回,我想立即获取 Javascript 日期对象,而不必担心格式。

感谢您的建议,

彼得

【问题讨论】:

    标签: javascript spring extjs


    【解决方案1】:

    您不会避免将日期序列化为某种格式。 Javascript 不理解 java 对象,因此必须有一些序列化步骤(无论是 json、xml 还是其他)。

    最好的办法是将日期发送为ISO 字符串并在其上使用Date.parse(isostring)。您不需要指定格式字符串,因此您必须输入更少的内容,至少您可以使用大多数客户理解的格式。

    【讨论】:

    • 我知道我必须以某种方式序列化/反序列化对象。我只是希望它为我透明/自动完成。在您提出的解决方案中,我需要在每个日期都在 Javascript 中添加“Date.parse”。我希望服务器为我添加这些“Date.parse”调用。因此,不是服务器在呈现 JSP 时将 JSON 粘合到 HTML 中,而是将 Javascript 和 JSON 的组合粘合起来,最终会创建常规的 JS 对象(就像我的问题中的示例一样)。是否有一些库或 Spring 机制可以做到这一点?
    • @machinery 那是 IMO 超出了 spring 范围,但是有一些流行的 js 库的扩展可以自动将日期字符串转换为 javascript 日期(example for jquery,没有测试它)。
    【解决方案2】:
    <c:set var="myModelObject" value="${myObjectFromServer}"/>
    
     <script>
       var myJSvar = "${myModelObject}";
     </script>
    

    是的,您必须对日期进行序列化/反序列化...我扩展了 PropertyEditor:

    public class LocalDateEditor extends PropertyEditorSupport{
        @Override
        public void setAsText(String text) throws IllegalArgumentException{
            setValue(DateTimeFormat.forPattern("dd MMM yyyy").print(text));
        }
    

    然后在你的控制器中注册(你也可以设置一个全局的,但我不记得如何):

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDate.class, new LocalDateEditor());
    }
    

    为了它的价值,我使用了一个全局日期格式化程序,并在用户界面上使用了一个全局 jquery ui datepicker 类——实际上根本不需要太多编码。一切都是开箱即用的——在初始设置之后。我从不喜欢 iso 标准日期(可能是因为我是英国人 :-( )

    【讨论】:

    • 但这会被渲染成这样的东西,对吧? var myJSvar = "2012 年 3 月 12 日";请参阅我对灵魂检查答案的评论。谢谢:)
    • 这正是它要做的。听起来您希望服务器为您创建客户端代码 - 这听起来像是一个坏主意恕我直言。您正在混合控制器和视图(来自 MVC 的 V 和 C)。 GWT 和 Vaadin 消除了编写 javascript 的需要。
    • 嗯.. 我不反对编写一些 Javascript,但感谢您的提示。我认为在我的情况下,视图和控制器混合是合理的。它可以让我删除一些样板代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多