一尘不染

Spring AJAX将对象列表从控制器发送到JSP

jsp

我试图将我从数据库获得的对象的发送列表发送到我的JSP。我设法成功地将数据从JSP发送到控制器。控制器内部的方法采用该参数,填充List(我在调试模式下检查了它),然后控制器返回该列表。

@RequestMapping(value="/test.html", method=RequestMethod.GET, produces="application/json")
public @ResponseBody List<ModelVechicle> fetchListModelById(@RequestParam Integer number) {

    System.out.println(number);

    List<ModelVechicle> modelList = vechicleService.fetchModelById(number);

    return  modelList; 
}

当我尝试在JSP上获取该列表时,我得到

HTTP Status 406 -

type Status report

message

description The resource identified by this request is only capable of generating 
responses with characteristics not acceptable according to the request "accept" headers.

Apache Tomcat/8.0.32

这是我的带有AJAX代码的JSP

<script type="text/javascript">
$(document).ready(function(){
    $("#brand").change(onSelectChange);
});

function onSelectChange() {
    var selected = $("#brand option:selected");     
    var output = "";
    var number = parseInt(selected.val());


      $.ajax({
            type: "GET",
            url: "test.html",
            dataType : 'json',
            data: ({number: number}),
             success: function(response){
                 $('#result').html("");
                    var obj = JSON.parse(response);
                    $('#result').html(obj.modelName);
                },
                error: function(xhr,e){                     
                    alert('Error while request..'+xhr.responseText);
                }
            });

    if(selected.val() != 0){
        output = "You selected brand " + selected.text();

    }
    $("#output").html(number);


}

这也是我的ModelVechicle类,也就是我要添加到List中的对象的类:

@Entity
@Table(name = "CARDEALERSHIP.MODEL")
public class ModelVechicle implements Serializable {

private static final long serialVersionUID = 7420515051961158192L;

@Id
@Column(name = "ID")
private Integer modelId;

@Column(name = "MODELNAME")
private String modelName;

@ManyToOne
@JoinColumn(name = "BRANDID")
private Brand brand;

public ModelVechicle(Integer modelId, String modelName, Brand brand) {
    super();
    this.modelId = modelId;
    this.modelName = modelName;
    this.brand = brand;
}

public ModelVechicle() {}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((brand == null) ? 0 : brand.hashCode());
    result = prime * result + ((modelId == null) ? 0 : modelId.hashCode());
    result = prime * result + ((modelName == null) ? 0 : modelName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    ModelVechicle other = (ModelVechicle) obj;
    if (brand == null) {
        if (other.brand != null)
            return false;
    } else if (!brand.equals(other.brand))
        return false;
    if (modelId == null) {
        if (other.modelId != null)
            return false;
    } else if (!modelId.equals(other.modelId))
        return false;
    if (modelName == null) {
        if (other.modelName != null)
            return false;
    } else if (!modelName.equals(other.modelName))
        return false;
    return true;
}

public Integer getModelId() {
    return modelId;
}

public void setModelId(Integer modelId) {
    this.modelId = modelId;
}

public String getModelName() {
    return modelName;
}

public void setModelName(String modelName) {
    this.modelName = modelName;
}

public Brand getBrand() {
    return brand;
}

public void setBrand(Brand brand) {
    this.brand = brand;
}

有人可以解释一下我如何做才能使List动态到达JSP页面,并正确显示List成员吗?

编辑:这是我的web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>CarDealership</display-name>
  <welcome-file-list>
    <welcome-file>addVechicle.html</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>springDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatchers.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>springDispatcher</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/app-config.xml
    </param-value>
  </context-param>

</web-app>

阅读 241

收藏
2020-06-10

共1个答案

一尘不染

从Spring 3.2+开始,在eval Accept标头之前,内容协商还需要考虑其他因素:

https://spring.io/blog/2013/05/11/content-negotiation-using-spring-
mvc:

在Spring MVC中启用内容协商

Spring支持几种用于选择所需格式的约定:URL后缀和/或URL参数。这些与使用Accept标头一起工作。结果,可以以三种方式中的任何一种来请求内容类型。默认情况下,将按以下顺序检查它们:

* 在URL中添加路径扩展名(后缀)。因此,如果传入的URL是类似http://myserver/myapp/accounts/list.html的内容,则需要HTML。对于电子表格,URL应该为
http://myserver/myapp/accounts/list.xls。后缀到媒体类型的映射是通过JavaBeans激活框架或JAF自动定义的(因此,activation.jar必须在类路径上)。
* 像这样的URL参数:http:// myserver / myapp / accounts / list?format =
xls
。参数的名称默认为格式,但是可以更改。默认情况下,禁用参数使用,但启用后将对其进行第二次检查。

  • 最后,检查“接受HTTP标头”属性。这实际上是HTTP定义为工作的方式,但是,如前所述,使用它可能会出现问题。

这实际上意味着,如果您映射@Controller带有.htm(l)后缀的方法,则即使您发送其他格式作为标头,它也将返回html并且不会返回json任何其他格式Accept

.htm一直将控制器映射为,并且@ResponseBody当我升级到Spring 3.2和更高版本时,必须更改用于映射带注释的方法的方式。

编辑: 按照我的预期,在看到您的web.xml之后,您正在将每个.html后缀请求映射到调度程序servlet:

  `<servlet-mapping>
    <servlet-name>springDispatcher</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>`

我认为现在@RequestMapping控制器中的就像这样:

@RequestMapping(value="/test", method=RequestMethod.GET, produces="application/json")
public @ResponseBody List<ModelVechicle> fetchListModelById(@RequestParam Integer number) {

由于/test不匹配.html后缀,请求没有到达springDispatcher,这就是为什么您得到404的原因。

现在,解决此问题的选项:

1)在web.xml中添加一个与此控制器匹配的新映射:

<servlet-mapping>
    <servlet-name>springDispatcher</servlet-name>
    <url-pattern>*.html</url-pattern>
    <url-pattern>*/test</url-pattern>
</servlet-mapping>

这样,您将被迫包括任何新的非html返回方法。对我来说似乎不可用。

2)将所有传入请求映射到dispatcherServlet

  <servlet-mapping>
    <servlet-name>springDispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

我不太喜欢这个选项,我更喜欢过滤我真正想要到达的分派器servlet的内容。

3)为这种请求找到新的匹配模式。我总是发布某种通用后缀,而JAF不会捕获它,例如* .service:

  <servlet-mapping>
    <servlet-name>springDispatcher</servlet-name>
    <url-pattern>*.html</url-pattern>
    <url-pattern>*.service</url-pattern>
  </servlet-mapping>

因此,在返回XML或JSON(或仅取决于Accept标题的任何其他格式)的Controller方法中,我这样映射:

@RequestMapping(value="/test.service", method=RequestMethod.GET, produces="application/json")
public @ResponseBody List<ModelVechicle> fetchListModelById(@RequestParam Integer number) {

4)您还可以使用’
http://com.xxx.yyy/myApp/service/resource
‘模式发布所有此类@ResponseBody控制器方法,并/service/在web.xml中用作servlet映射

      <servlet-mapping>
        <servlet-name>springDispatcher</servlet-name>
        <url-pattern>*.html</url-pattern>
        <url-pattern>/service/</url-pattern>
      </servlet-mapping>
2020-06-10