Java 将一个简单的映射结构从 spring mvc 控制器返回到 ajax

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28893796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 06:59:57  来源:igfitidea点击:

Returning a simple map structure from spring mvc controller to ajax

javaajaxjsonspring-mvcHymanson

提问by Mike

I am using spring mvc 4 and trying to return a simple mapto 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 1and hellofrom ajax as expected.

警报1hello从阿贾克斯预期。

I added the Hymanson jar files as expected (by pom.xml):

我按预期添加了 Hymanson jar 文件(通过 pom.xml):

dependency>
        <groupId>com.fasterxml.Hymanson.core</groupId>
        <artifactId>Hymanson-core</artifactId>
        <version>2.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.Hymanson.core</groupId>
        <artifactId>Hymanson-databind</artifactId>
        <version>2.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.Hymanson.core</groupId>
        <artifactId>Hymanson-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

提前致谢!麦克风

回答by StanislavL

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 (e.g. 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. This is done using 'accept headers' of the following types:

客户端(例如您的 Web 浏览器或我们的 CheckUpDown 机器人)可以向 Web 服务器(运行网站)指示它将从 Web 服务器接收回的数据的特征。这是使用以下类型的“接受标头”完成的:

Accept: The MIME types accepted by the client. For example, a browser may only accept back types of data (HTML files, GIF files etc.) it knows how to process. Accept-Charset: The character sets accepted by the client. Accept-Encoding: The data encoding accepted by the client e.g. the file formats it understands. Accept-Language: The natural languages (English, German etc.) accepted by the client. Accept-Ranges: Whether the client accepts ranges of bytes from the resource i.e. a portion of the resource. 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.

接受:客户端接受的 MIME 类型。例如,浏览器可能只接受它知道如何处理的返回类型的数据(HTML 文件、GIF 文件等)。Accept-Charset:客户端接受的字符集。Accept-Encoding:客户端接受的数据编码,例如它理解的文件格式。Accept-Language:客户端接受的自然语言(英语、德语等)。Accept-Ranges:客户端是否接受来自资源的字节范围,即资源的一部分。如果 Web 服务器检测到它要返回的数据不被客户端接受,它会返回一个包含 406 错误代码的标头。

It means you somehow should change your server logic to accept MIME/Charset/Encoding etc. of the request you sent from client. Can't say exactly what's wrong but try to play with headers and consumes of the RequestMapping.

这意味着您应该以某种方式更改服务器逻辑以接受您从客户端发送的请求的 MIME/Charset/Encoding 等。不能确切地说出了什么问题,但尝试使用 RequestMapping 的标头和消耗。

回答by Tkachuk_Evgen

Try this:

尝试这个:

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

回答by ema

You need this dependency :

你需要这个依赖:

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

Add this if already haven't :

如果还没有,请添加:

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

回答by Master Slave

Your "problem" is due to your request ending in .html. You need to add the following configuration to make it work as you expect

您的“问题”是由于您的请求以.html. 您需要添加以下配置以使其按预期工作

<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 建议的那样添加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 (e.g. .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. However with the request

你正在恢复 HTML。但是随着请求

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 JSONback from the server, however, .html is hinting that it should be HTMLinstead, 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 配置版本

回答by 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 }

谢谢大家!迈克 }

回答by V.R.Manivannan

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 控制器代码应如下所示:

@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 linkfor understanding the library which support this functionality.

您还可以参考此链接以了解支持此功能的库。