使用Spring 3.2.0.RELEASE的DeferredResult反转ajax。不在IE中工作 [英] Reverse ajax using DeferredResult of Spring 3.2.0.RELEASE. Not working in IE

查看:66
本文介绍了使用Spring 3.2.0.RELEASE的DeferredResult反转ajax。不在IE中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Spring中的反向ajax创建群聊的演示。我使用的是Spring 3.2.0.RELEASE版本。

I am trying to create a demo of Group Chat using reverse ajax in Spring. I am using Spring 3.2.0.RELEASE version.

我正在使用DeferredResult在我的控制器中执行反向ajax。以下是我的Controller类的片段。

I am using DeferredResult to perform reverse ajax in my controller. Following is the snippet of my Controller class.

@Autowired
private AsyncRepository asyncRepository;

Map<Integer, List<DeferredResult<String>>> watchers = new ConcurrentHashMap<Integer, List<DeferredResult<String>>>();

@RequestMapping(value="/asyncRequest/getMessages/{id}", method=RequestMethod.GET)
@ResponseBody
public DeferredResult<String> getMessages(final @PathVariable("id") Integer id){
    final DeferredResult<String> deferredResult = new DeferredResult<String>(null, Collections.emptyList());

    if(watchers.containsKey(id)) {
        watchers.get(id).add(deferredResult);
    } else {
        watchers.put(id, new ArrayList<DeferredResult<String>>());
        watchers.get(id).add(deferredResult);
    }

    deferredResult.onCompletion(new Runnable() {
        @Override
        public void run() {
            watchers.get(id).remove(deferredResult);
        }
    });

    return deferredResult;
}

@RequestMapping(value="/asyncRequest/setMessages/{id}/{message}", method=RequestMethod.GET)
@ResponseBody
public String setMessage(@PathVariable("id") Integer id, @PathVariable("message") String message) {
    asyncRepository.setMessage(id, message);

    return "";
}

@Scheduled(fixedRate=1000)
public void processQueues() {
    for (Map.Entry<Integer, Queue<AsyncDataBean>> entry : asyncRepository.getAsyncBeans().entrySet()) {
        while(entry != null && entry.getValue() != null && !entry.getValue().isEmpty()) {
            AsyncDataBean asyncDataBean = entry.getValue().poll();
            for (DeferredResult<String> deferredResult : watchers.get(asyncDataBean.getId())) {
                deferredResult.setResult(asyncDataBean.getMessage());
            }
        }
    }
}

下面是Repository类,它包含GroupID的Map及其相关的messageQueue。它还具有获取和设置相关组ID的消息的功能。

And below is the Repository class which holds the Map of GroupID and its relevant messageQueue. And it also has the functions for getting and setting the messages for relevant group id.

@Repository
public class AsyncRepository {

    private Map<Integer, Queue<AsyncDataBean>> asyncBeans = new ConcurrentHashMap<Integer, Queue<AsyncDataBean>>();

    public String getMessages(Integer id) {
        StringBuilder stringBuilder = new StringBuilder();
        while (asyncBeans.get(id) != null && !asyncBeans.get(id).isEmpty()) {
            stringBuilder.append(asyncBeans.get(id).poll().getMessage()).append("~");
        }

        return stringBuilder.toString();
    }

    public void setMessage(Integer id, String message) {
        if(asyncBeans.containsKey(id)) {
            asyncBeans.get(id).add(new AsyncDataBean(id, message));
        } else {
            Queue<AsyncDataBean> messageQueue = new ConcurrentLinkedQueue<AsyncDataBean>();
            messageQueue.add(new AsyncDataBean(id, message));
            asyncBeans.put(id, messageQueue);
        }
    }

    public Map<Integer, Queue<AsyncDataBean>> getAsyncBeans() {
        return asyncBeans;
    }

    public void setAsyncBeans(Map<Integer, Queue<AsyncDataBean>> asyncBeans) {
        this.asyncBeans = asyncBeans;
    }
}

以下是我用来存储的数据bean每条消息及其组ID。

And below is the data bean I am using to store each message with its group id.

public class AsyncDataBean {
    private Integer id;
    private String message;

    public AsyncDataBean() {
    }

    public AsyncDataBean(int id, String message) {
        this.setId(id);
        this.setMessage(message);
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

然后是群组聊天的jsp页面。如下所示。

And then comes the jsp page for group chat. which looks like below.

<script type="text/javascript">
    var messagesWaiting = false;
    function getMessages(){
        if(!messagesWaiting){
            $.ajax({ url: "${pageContext.servletContext.contextPath}/asyncRequest/getMessages/${id}", 
                     dataType:"text",
                     success: function(data,textStatus,jqXHR) {
                         if(textStatus == 'success'){
                             messagesWaiting = false;
                             var arr = data.split("~");
                             for(var i=0; i<arr.length; i++)
                             {
                                    try
                                    {
                                        if(arr[i] != '') {
                                            $("#txtaMessages").val($("#txtaMessages").val() + "\n\n" + arr[i]);
                                            document.getElementById("txtaMessages").scrollTop = document.getElementById("txtaMessages").scrollHeight;
                                        }
                                    }
                                    catch(e){
                                     alert(e.message);
                                    }
                             }
                         }
                     }, 
                     complete: function(j) {
                     },
                     error: function(xhr) { 
                     }
            });
            messagesWaiting = true;
        }
    }
    setInterval(getMessages, 1000);
    getMessages();

    function sendMessage() {
        var xmlhttp1 = new XMLHttpRequest();
        xmlhttp1.open("GET", '${pageContext.servletContext.contextPath}/asyncRequest/setMessages/${id}/' + $("#txtMessage").val(), true);
        xmlhttp1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xmlhttp1.send();
        $("#txtMessage").val("");
        $("#txtMessage").focus();
    }
</script>

</head>
<body>
    <h1>Hello World!</h1>
    <table>
        <tr>
            <td>Messages :: </td>
            <td>
                <textarea cols="100" rows="10" id="txtaMessages"></textarea>
            </td>
        </tr>
        <tr>
            <td>Send Message :: </td>
            <td><input type="text" id="txtMessage"/></td>
        </tr>
        <tr>
            <td><input type="button" value="Send" onclick="sendMessage();"/></td>
        </tr>
    </table>
</body>
</html>

这就是我迄今为止编写的代码。一切都在FF和Chrome中运行。但在IE中,它没有按预期工作。该请求永远不会在服务器上保留,并且始终按照javascript代码中的配置每秒执行一次。它总是返回与之前相同的结果。我曾尝试使用其他几种方法来发送IE的ajax请求,但它无法正常工作。任何人都可以让它为我工作吗?

That is what I have coded till now to get this working. And everything is working finw in FF and Chrome. But in IE it is not working as expected. The request is never gets hold on the server and it always gets executed every second as configured in the javascript code. And it always returns the same result as previous. I have tried to use several other methods to send ajax request for IE but its not working. Can anyone get it working for me?

由于在FF和Chrome中一切正常,我怀疑问题是使用javascript代码发送请求以获取消息。

Since everything works fine in FF and Chrome, I suspect the problem is with javascript code to send the request to get messages.

请帮助我。

提前致谢。

推荐答案

这非常令人沮丧。

为了让这个东西在IE中正常工作,我需要在ajax请求中设置 cache:false 属性我是使用jquery为getMessages创建。否则IE将不会将请求保留在挂起状态,并始终返回旧的响应文本。

To get this thing work properly in IE I need to set cache:false attribute in the ajax request I am creating with jquery for getMessages. Otherwise IE will not hold the request in pending status and always returns back with the old response text.

这是IE的一个非常大的问题。我希望没有人再次面对这个问题,或者尽早找到答案。

Its a very big issue with IE. I hope no one face the problem again or finds this answer as early as possible.

:)

这篇关于使用Spring 3.2.0.RELEASE的DeferredResult反转ajax。不在IE中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆