gpt4 book ai didi

json - Spring 3.2 中 AJAX 的 PUT 方法不起作用

转载 作者:行者123 更新时间:2023-11-30 23:43:28 25 4
gpt4 key购买 nike

我正在尝试使用以下 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);
}
});
}

它尝试在 Spring 中调用以下方法。

@RequestMapping(value=("ajax/UpdateUserRole"), method=RequestMethod.PUT)
public @ResponseBody void updateUserRole(@RequestParam(value=("id")) String id)
{
System.out.println("id = "+id);
}

FireFox 响应以下错误。

HTTP Status 405 - Request method 'GET' not supported

type Status report

message Request method 'GET' not supported

description The specified HTTP method is not allowed for the requested resource (Request method 'GET' not supported).

Apache Tomcat/6.0.26

它可以与 GETPOST 方法配合使用,并且 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>

如何使 GETPOST 之外的 HTTP 方法在 Spring 3.2 中工作?

<小时/>

编辑:

根据下面的评论,以下是我的整个 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>

最佳答案

除非仅使用路径参数,否则处理常规 HTTP PUT 需要更多工作。

Since Spring 3.1, HttpPutFormContentFilter 可用于制作@RequestParamapplication/x-www-form-urlencoded 工作数据:

Filter that makes form encoded data available through the ServletRequest.getParameter*() family of methods during HTTP PUT requests.

The Servlet spec requires form data to be available for HTTP POST but not for HTTP PUT requests. This filter intercepts HTTP PUT requests where content type is 'application/x-www-form-urlencoded', reads form encoded content from the body of the request, and wraps the ServletRequest in order to make the form data available as request parameters just like it is for HTTP POST requests.

但是:这个过滤器consumes请求的输入流,使其不可用于 FormHttpMessageConverter 等转换器,就像用于 @RequestBody MultiValueMap<String, String>HttpEntity<MultiValueMap<String, String>> 。结果,一旦你有 configured如果您的应用程序中使用上述过滤器,则在调用使用也需要原始 application/x-www-form-urlencoded 的其他转换器的方法时,您将收到“IOException:流已关闭”放置数据。


或者可以使用 @RequestBody 手动完成所有事情HttpEntity<?> :

@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;
}

另请参阅an example using WebDataBinder ,或使用:

public ResponseEntity<String> updateUserRole(
final HttpEntity<MultiValueMap<String, String>> entity) {
Map<String, String> params = entity.getBody().toSingleValueMap();
String id = params.get("id");
...

请注意,为了进行测试,请使用 MockMvc's mockMvc.perform(put(url).param(name, value))实际上也可以处理问题中的代码,即使它在 servlet 容器中会失败。但是 MockMvc 没有在这样的 servlet 容器中运行,因此有点欺骗你。

MockMvc 的 .param(name, value)也可以与 HttpPutFormContentFilter 很好地配合使用。但是使用MockMvc测试时@RequestBodyHttpEntity<?> ,还需要创建任何 application/x-www-form-urlencoded手动放置内容。喜欢:

mockMvc.perform(put(url).content("id=" + URLEncoder.encode(id, "UTF-8")
+ "&a=" + URLEncoder.encode(a, "UTF-8") + "&b=" + ...)

能够简单地使用.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;
}
};
}

...然后使用 .with(convertParameters())旁边.param(name, value) :

mockMvc.perform(put(url)
.with(convertParameters())
.param("id", id).param("a", a).param("b", b) ...)

鉴于上述所有内容,只需使用 HttpPutFormContentFilter对于 application/x-www-form-urlencoded数据确实让生活变得更轻松。

当浏览器不发送application/x-www-form-urlencoded时数据,但诸如 JSON 之类的东西,然后尝试映射到 MultiValueMap将产生 415 不支持的媒体类型。相反,使用类似 @RequestBody MyDTO data 的内容或HttpEntity<MyDTO> entityParsing JSON in Spring MVC using Jackson JSON 中所述.

关于json - Spring 3.2 中 AJAX 的 PUT 方法不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14416078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com