Tin*_*iny 5 jquery spring json put jackson
我正在尝试使用以下jQuery 1.6通过AJAX 在Spring(3.2.0)中调用一个方法.
function updateRoleEnabled(id)
{
$.ajax({
datatype:"json",
type: "PUT",
url: "/wagafashion/ajax/UpdateUserRole.htm",
data: "id="+id+"&t="+new Date().getTime(),
success: function(response)
{
},
error: function(e)
{
alert('Error: ' + e);
}
});
}
Run Code Online (Sandbox Code Playgroud)
它试图在Spring中调用以下方法.
@RequestMapping(value=("ajax/UpdateUserRole"), method=RequestMethod.PUT)
public @ResponseBody void updateUserRole(@RequestParam(value=("id")) String id)
{
System.out.println("id = "+id);
}
Run Code Online (Sandbox Code Playgroud)
FireFox响应以下错误.
HTTP状态405 - 不支持请求方法"GET"
类型状态报告
消息请求方法'GET'不受支持
description对于请求的资源,不允许使用指定的HTTP方法(不支持请求方法'GET').
Apache Tomcat/6.0.26
它适用于GET和POST方法和JSON(与Jackson-2.1.1)也适用于应用程序的其他部分.
如果需要查看dispatcher-servlet.xml文件,完整内容如下.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="controller" />
<context:component-scan base-package="validatorbeans" />
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" >
<mvc:message-converters register-defaults="false">
<bean id="jacksonMessageConverter" p:supportedMediaTypes="application/json" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="false" />
<property name="ignoreAcceptHeader" value="false" />
<property name="mediaTypes" >
<value>
atom=application/atom+xml
html=text/html
json=application/json
*=*/*
</value>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">
fileUploadingFailure
</prop>
</props>
</property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
Run Code Online (Sandbox Code Playgroud)
如何在Spring 3.2 之外制作HTTP方法GET并POST在其中工作?
编辑:
根据以下评论,以下是我的整个web.xml文件.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>NoCacheFilter</filter-name>
<filter-class>filter.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>NoCacheFilter</filter-name>
<url-pattern>/admin_side/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>FileUploadFilter</filter-name>
<filter-class>com.ckfinder.connector.FileUploadFilter</filter-class>
<init-param>
<param-name>sessionCookieName</param-name>
<param-value>JSESSIONID</param-value>
</init-param>
<init-param>
<param-name>sessionParameterName</param-name>
<param-value>jsessionid</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FileUploadFilter</filter-name>
<url-pattern>
/ckfinder/core/connector/java/connector.java
</url-pattern>
</filter-mapping>
<filter>
<filter-name>multipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<description>ServletContextListener</description>
<listener-class>listener.UnregisterDatabaseDrivers</listener-class>
</listener>
<servlet>
<servlet-name>ConnectorServlet</servlet-name>
<servlet-class>com.ckfinder.connector.ConnectorServlet</servlet-class>
<init-param>
<param-name>XMLConfig</param-name>
<param-value>/WEB-INF/config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ConnectorServlet</servlet-name>
<url-pattern>
/ckfinder/core/connector/java/connector.java
</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<error-page>
<description>Missing login</description>
<error-code>401</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Forbidden directory listing</description>
<error-code>403</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Missing page</description>
<error-code>404</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Uncaught exception</description>
<error-code>500</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Unsupported servlet method</description>
<error-code>503</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
Run Code Online (Sandbox Code Playgroud)
除非仅使用路径参数,否则处理常规 HTTP PUT 需要更多工作。
从Spring 3.1 开始,HttpPutFormContentFilter可用于@RequestParam为application/x-www-form-urlencoded数据工作:
过滤器,使表单编码数据
ServletRequest.getParameter*()在 HTTP PUT 请求期间通过一系列方法可用。Servlet 规范要求表单数据可用于 HTTP POST,但不可用于 HTTP PUT 请求。此过滤器拦截内容类型为“
application/x-www-form-urlencoded”的 HTTP PUT 请求,从请求正文中读取表单编码内容,并包装 ServletRequest 以使表单数据可用作请求参数,就像 HTTP POST 请求一样。
但是:此过滤器消耗请求的输入流,使其无法用于转换器FormHttpMessageConverter,例如 ,如用于@RequestBody MultiValueMap<String, String>或HttpEntity<MultiValueMap<String, String>>。因此,在应用程序中配置application/x-www-form-urlencoded上述过滤器后,在调用使用也需要原始PUT 数据的其他转换器的方法时,您将收到“IOException:流已关闭”。
或者,可以使用或手动完成所有操作:@RequestBodyHttpEntity<?>
@RequestMapping(value="ajax/UpdateUserRole", method=RequestMethod.PUT,
produces = MediaType.TEXT_PLAIN_VALUE)
public @ResponseBody String updateUserRole(
@RequestBody final MultiValueMap<String, String> data,
final HttpServletResponse response) {
Map<String, String> params = data.toSingleValueMap();
String id = params.get("id");
String a = params.get("a");
String b = params.get("b");
if(id == null || a == null || b == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return null;
}
return "id = " + id;
}
Run Code Online (Sandbox Code Playgroud)
另请参阅使用 的示例WebDataBinder,或使用:
public ResponseEntity<String> updateUserRole(
final HttpEntity<MultiValueMap<String, String>> entity) {
Map<String, String> params = entity.getBody().toSingleValueMap();
String id = params.get("id");
...
Run Code Online (Sandbox Code Playgroud)
请注意,对于测试,使用MockMvc mockMvc.perform(put(url).param(name, value))实际上也可以处理问题中的代码,即使它在 servlet 容器中会失败。但是 MockMvc 没有在这样的 servlet 容器中运行,因此有点欺骗你。
MockMvc.param(name, value)也可以很好地与HttpPutFormContentFilter. 但是当使用 MockMvc 来测试@RequestBody或 时HttpEntity<?>,还需要application/x-www-form-urlencoded手动创建任何 PUT 内容。喜欢:
mockMvc.perform(put(url).content("id=" + URLEncoder.encode(id, "UTF-8")
+ "&a=" + URLEncoder.encode(a, "UTF-8") + "&b=" + ...)
Run Code Online (Sandbox Code Playgroud)
为了能够简单地使用.param(name, value),就像 GET 和 POST 一样,可以定义:
public static RequestPostProcessor convertParameters() {
return new RequestPostProcessor() {
@Override
public MockHttpServletRequest postProcessRequest(
final MockHttpServletRequest request) {
if ("PUT".equalsIgnoreCase(request.getMethod()) {
Map<String, String[]> params = request.getParameterMap();
if (params != null) {
StringBuilder content = new StringBuilder();
for (Entry<String, String[]> es : params.entrySet()) {
for (String value : es.getValue()) {
try {
content.append(URLEncoder.encode(es.getKey(), "UTF-8"))
.append("=")
.append(URLEncoder.encode(value, "UTF-8"))
.append("&");
}
catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("UTF-8 not supported");
}
}
}
request.setParameters(new HashMap<String, String[]>());
request.setContent(content.toString().getBytes());
request.setContentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE);
}
}
return request;
}
};
}
Run Code Online (Sandbox Code Playgroud)
...然后使用.with(convertParameters())旁边.param(name, value):
mockMvc.perform(put(url)
.with(convertParameters())
.param("id", id).param("a", a).param("b", b) ...)
Run Code Online (Sandbox Code Playgroud)
鉴于上述所有内容,简单地使用HttpPutFormContentFilter数据application/x-www-form-urlencoded确实让生活变得更轻松。
当浏览器不发送application/x-www-form-urlencoded数据,而是发送 JSON 等内容时,尝试映射到MultiValueMap将产生 415 不支持的媒体类型。相反,请使用类似@RequestBody MyDTO data或HttpEntity<MyDTO> entity如使用 Jackson JSON 在 Spring MVC 中解析 JSON中所解释的内容。
| 归档时间: |
|
| 查看次数: |
5774 次 |
| 最近记录: |