我试图将我从数据库获得的对象的发送列表发送到我的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>
从Spring 3.2+开始,在eval Accept标头之前,内容协商还需要考虑其他因素:
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定义为工作的方式,但是,如前所述,使用它可能会出现问题。
在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。参数的名称默认为格式,但是可以更改。默认情况下,禁用参数使用,但启用后将对其进行第二次检查。
这实际上意味着,如果您映射@Controller带有.htm(l)后缀的方法,则即使您发送其他格式作为标头,它也将返回html并且不会返回json任何其他格式Accept。
@Controller
.htm(l)
html
json
我.htm一直将控制器映射为,并且@ResponseBody当我升级到Spring 3.2和更高版本时,必须更改用于映射带注释的方法的方式。
.htm
@ResponseBody
编辑: 按照我的预期,在看到您的web.xml之后,您正在将每个.html后缀请求映射到调度程序servlet:
`<servlet-mapping> <servlet-name>springDispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping>`
我认为现在@RequestMapping控制器中的就像这样:
@RequestMapping
@RequestMapping(value="/test", method=RequestMethod.GET, produces="application/json") public @ResponseBody List<ModelVechicle> fetchListModelById(@RequestParam Integer number) {
由于/test不匹配.html后缀,请求没有到达springDispatcher,这就是为什么您得到404的原因。
/test
.html
现在,解决此问题的选项:
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映射
/service/
<servlet-mapping> <servlet-name>springDispatcher</servlet-name> <url-pattern>*.html</url-pattern> <url-pattern>/service/</url-pattern> </servlet-mapping>