简体   繁体   English

从spring mvc controller返回一个简单的map结构到ajax

[英]Returning a simple map structure from spring mvc controller to ajax

I am using spring mvc 4 and trying to return a simple map to ajax - from my controller to jsp file. 我正在使用spring mvc 4并尝试将一个简单的map返回到ajax - 从我的控制器到jsp文件。

The controller: 控制器:

    @RequestMapping(value = "/ajaxtest", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, String> myTest() {
        System.out.println("------------------------------------test");

        Map<String,String> myMap = new HashMap<String, String>();
        myMap.put("a", "1");
        myMap.put("b", "2");
        return myMap;
    }

Ajax from the jsp file: 来自jsp文件的Ajax:

function testAjax() {
        $.ajax({
            url : '../../ajaxtest.html',
            dataType: "json",
            contentType: "application/json;charset=utf-8",
            success : function(data) {
                alert("1");
                alert(data);
            }
        });
    }

But I am not getting any alert but just the error HTTP/1.1 406 Not Acceptable . 但我没有得到任何警报,只是错误HTTP/1.1 406 Not Acceptable

However, changing the code to return a simple string works fine. 但是,更改代码以返回一个简单的字符串工作正常。 Controller: 控制器:

    @RequestMapping(value = "/ajaxtest", method = RequestMethod.GET)
    public @ResponseBody
    String myTest() {
        System.out.println("------------------------------------test");
        return "hello";
}   

Ajax: 阿贾克斯:

function testAjax() {
        $.ajax({
            url : '../../ajaxtest.html',
            success : function(data) {
                alert("1");
                alert(data);
            }
        });
    }

Alerting 1 and hello from ajax as expected. 按预期从ajax发出警报1hello

I added the jackson jar files as expected (by pom.xml): 我按预期添加了jackson jar文件(通过pom.xml):

dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.5.1</version>
    </dependency>

Am I missing something? 我错过了什么吗? I just want to return a simple mapping structure (or other class structure in the future). 我只想返回一个简单的映射结构(或将来的其他类结构)。

Update : From spring console (Don't sure it's related): Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation 更新 :从spring控制台(不确定它是否相关): Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

Thanks in advance! 提前致谢! Mike 麦克风

I don't know if it the correct way but I solved it as following. 我不知道它是否正确,但我解决了以下问题。

In the controller, I converted the map to json: 在控制器中,我将地图转换为json:

    @RequestMapping(value = "/ajaxtest", method = RequestMethod.GET)
    public @ResponseBody
    String myTest() {
        System.out.println("------------------------------------random");

        Map<String,String> myMap = new HashMap<String, String>();
        myMap.put("a", "1");
        myMap.put("b", "2");
        ObjectMapper mapper = new ObjectMapper();
        String json = "";
        try {
            json = mapper.writeValueAsString(myMap);
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return json;
}

and in the jsp: 在jsp中:

function testAjax() {
        $.ajax({
            url : '../../ajaxtest.html',
            type:"GET",
            contentType: "application/json;charset=utf-8",
            success : function(data) {
                alert("1");
                alert(data);
                var obj = jQuery.parseJSON( data );
                alert(obj.a);
                alert(obj.b);
            }
        });

Thanks you all! 谢谢大家! Mike } 迈克}

Try to add consumes="application/json" and produces={ "application/json"} to the @RequestMapping to let spring process your json 尝试添加consumes="application/json"produces={ "application/json"}到@RequestMapping让spring处理你的json

UPDATE 406 error description 更新406错误说明

HTTP Error 406 Not acceptable HTTP错误406不可接受

Introduction 介绍

A client (eg your Web browser or our CheckUpDown robot) can indicate to the Web server (running the Web site) the characteristics of the data it will accept back from the Web server. 客户端(例如您的Web浏览器或我们的CheckUpDown机器人)可以向Web服务器(运行Web站点)指示它将从Web服务器接收的数据的特征。 This is done using 'accept headers' of the following types: 这是使用以下类型的“接受标头”完成的:

Accept: The MIME types accepted by the client. 接受:客户端接受的MIME类型。 For example, a browser may only accept back types of data (HTML files, GIF files etc.) it knows how to process. 例如,浏览器可能只接受它知道如何处理的返回类型的数据(HTML文件,GIF文件等)。 Accept-Charset: The character sets accepted by the client. Accept-Charset:客户端接受的字符集。 Accept-Encoding: The data encoding accepted by the client eg the file formats it understands. Accept-Encoding:客户端接受的数据编码,例如它理解的文件格式。 Accept-Language: The natural languages (English, German etc.) accepted by the client. Accept-Language:客户接受的自然语言(英语,德语等)。 Accept-Ranges: Whether the client accepts ranges of bytes from the resource ie a portion of the resource. Accept-Ranges:客户端是否接受来自资源的字节范围,即资源的一部分。 If the Web server detects that the data it wants to return is not acceptable to the client, it returns a header containing the 406 error code. 如果Web服务器检测到它要返回的数据对客户端不可接受,则会返回包含406错误代码的标头。

It means you somehow should change your server logic to accept MIME/Charset/Encoding etc. of the request you sent from client. 这意味着您应该以某种方式更改服务器逻辑以接受从客户端发送的请求的MIME / Charset / Encoding等。 Can't say exactly what's wrong but try to play with headers and consumes of the RequestMapping. 不能确切地说出错了但是尝试使用RequestMapping的标题和消耗。

Your "problem" is due to your request ending in .html . 您的“问题”是由于您的请求以.html结尾。 You need to add the following configuration to make it work as you expect 您需要添加以下配置才能使其按预期工作

<bean id="contentNegotiationManager"              class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="defaultContentType" value="application/json" />
</bean>

 <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

and than do as @StanislavL suggested add the produces={ "application/json"} don't add the consumes cause your not posting any JSON 并且比@StanislavL建议添加produce produces={ "application/json"}不添加消耗因为你没有发布任何JSON

an explanation 一个解释

When spring determines the representation to which it converts it first looks at the path part of the request (eg .html, .json, .xml), than it looks for a parameter explicitly setting the conversion representation, finally goes for an Accept header (the so call PPA strategy) 当spring确定它转换的表示时,它首先查看请求的路径部分(例如.html,.json,.xml),而不是查找显式设置转换表示的参数,最后查找Accept标头(所以称PPA策略)

that is why your example works 这就是你的例子有效的原因

function testAjax() {
        $.ajax({
            url : '../../ajaxtest.html',
            success : function(data) {
                alert("1");
                alert(data);
            }
        });
    }

you're getting HTML back. 你正在获取HTML。 However with the request 但是有了请求

function testAjax() {
        $.ajax({
            url : '../../ajaxtest.html',
            dataType: "json",
            contentType: "application/json;charset=utf-8",
            success : function(data) {
                alert("1");
                alert(data);
            }
        });
    }

you're explicitly saying that you expect JSON back from the server, however, .html is hinting that it should be HTML instead, and you end up in problems 你明确地说你希望JSON从服务器返回,但是,.html暗示它应该是HTML ,而你最终会遇到问题

To learn the details of the content negotiation strategy you should read this blog , its almost famous by now :) It will also show you the pure java config version 要了解内容协商策略的细节,你应该阅读这个博客 ,它现在几乎是着名的:)它还将向你展示纯java配置版本

Your Ajax call should something similar to: 您的Ajax调用应该类似于:

$("#someId" ).click(function(){
            $.ajax({ 
                url:"getDetails",    
                type:"GET", 
                contentType: "application/json; charset=utf-8",
                success: function(responseData){
                    console.log(JSON.stringify(responseData));
                    // Success Message Handler
                },error:function(data,status,er) { 
                    console.log(data)
                 alert("error: "+data+" status: "+status+" er:"+er);
               }
            });
            });

Spring Controller Code should be as below : Spring Controller Code应如下所示:

@RequestMapping(value="/getDetails",method=RequestMethod.GET)
    public @ResponseBody Map<String,String> showExecutiveSummar(){
        Map<String,String> userDetails = new HashMap<String,String>();
        userDetails .put("ID","a" );
        userDetails .put("FirstName","b" );
        userDetails .put("MiddleName","c" );
        userDetails .put("LastName","d" );
        userDetails .put("Gender","e" );
        userDetails .put("DOB","f" );
    return userDetails 
    }

You can also refer to this link for understanding the library which support this functionality. 您还可以参考此链接以了解支持此功能的库。

Try this: 试试这个:

 $.ajax({
        type:"GET",
        url: "/ajaxtest",
        dataType: "json",
        contentType: "application/json;charset=utf-8",
        success: function(data){
        alert("1");
        alert(data);
    }
    });

You need this dependency : 你需要这种依赖:

<dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version></version>
    </dependency>

Add this if already haven't : 如果已经没有,请添加:

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
  <list>
    <ref bean="jacksonMessageConverter"/>
  </list>
</property>
</bean>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM