关于JSP不接受PUT请求,我遇到了这个问题.所以我想知道如何解决它.我已经在堆栈溢出中读到了这个相关的问题,但它没有解释如何修复它.
HTTP状态405 - JSP仅允许GET POST或HEAD
来自Rails的背景,我正在努力实现这一点,因此我使用了像PUT的rails REST样式进行更新,并使用DELETE来删除User资源.
但是,只要在此控制器中出现错误,它就会尝试将请求返回到原始JSP,但Tomcat 8.0.9不接受请求并提供此错误:"HTTP状态405 - JSP仅允许GET POST或HEAD".我已经尝试在Tomcat web.xml中禁用readonly - 它没有任何效果,我仍然得到错误.我把它切换到POST方法,流程工作正常.
有没有办法可以强制前进为POST方法,同时仍然接受请求的PUT方法?
/**
* Edit a user account.
* @return the edit user view
*/
@RequestMapping(value = {"/update/{userId}"}, method = RequestMethod.PUT)
public String updateUser(@Valid @ModelAttribute("user") User user, BindingResult result, final RedirectAttributes redirectAttributes)
{
logger.debug(user);
// we check for duplicate email addresses during the update operation.
List<User> userCheckList = userRepository.findByEmail(user.getEmail());
if (userCheckList.size() > 0)
{
// size of list should only ever be 1
User userCheck = userCheckList.get(0);
if (userCheck.getId() != user.getId())
{
result.rejectValue("email", "error.user", "An account already exists for this user email address.");
}
}
if (result.hasErrors())
{
return "admin.users.edit";
}
// we locate the user and add it to the model
userRepository.save(user);
// the save operation was successful so we show the user message.
redirectAttributes.addFlashAttribute("user", user);
redirectAttributes.addFlashAttribute("message", "Updated successfully");
String viewName = "redirect:/admin/users";
logger.debug(viewName);
return viewName;
}
Run Code Online (Sandbox Code Playgroud)
rya*_*anp 16
问题是,当您从控制器方法返回视图名称时,Spring DispatcherServlet将转发到给定视图,保留原始PUT方法.
在试图处理这个问题时,Tomcat会拒绝它,理由PUT是JSP可以被解释为"用服务器的内容替换此请求的内容".
您真的希望控制器处理您的PUT请求,然后再转发到您的JSP GET.幸运的是,Servlet 3.0提供了一种纯粹过滤FORWARD调度程序的方法.
创建一个过滤器:
public class GetMethodConvertingFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
// do nothing
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(wrapRequest((HttpServletRequest) request), response);
}
@Override
public void destroy() {
// do nothing
}
private static HttpServletRequestWrapper wrapRequest(HttpServletRequest request) {
return new HttpServletRequestWrapper(request) {
@Override
public String getMethod() {
return "GET";
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
然后把它连接到你的web.xml身上:
<filter>
<filter-name>getMethodConvertingFilter</filter-name>
<filter-class>my.GetMethodConvertingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>getMethodConvertingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)
这会将请求转换为GET仅转发,将请求通过其他调度程序保持不变,因此PUTs将被控制器正常拦截.
我的(可能是不正确的)理解是Tomcat 8.0.9引入了一个修复程序,它可以自动为ERROR调度程序完成- 请参阅链接问题中的答案.但是你没有使用容器的错误处理机制来呈现你的错误页面,你正在使用Spring MVC手动转发到视图,因此你需要这样做.我个人在Jetty 9.2.7下遇到了这个问题,没有这样的修复,我将错误处理委托给容器,所以我<dispatcher>ERROR</dispatcher>也在我的过滤器映射中配置了.
这一切看起来有点神秘但是我发现成功跳过这个特定的RESTful-Spring-JSP-web-application hoop的唯一方法.
| 归档时间: |
|
| 查看次数: |
5895 次 |
| 最近记录: |