最近在写JavaEE系列的文章,在写SpringMVC的REST风格URL的时候出现了一些问题,下面是部分代码。

index.jsp页面代码:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body><form action="springmvc/testRest/1" method="post"><input type="hidden" name="_method" value="PUT"> <input type="submit" value="TestRest PUT"></form><br><form action="springmvc/testRest/1" method="post"><input type="hidden" name="_method" value="DELETE"> <input type="submit" value="TestRest DELETE"></form><br><form action="springmvc/testRest" method="post"><input type="submit" value="TestRest POST"></form><br><form action="springmvc/testRest/1" method="get"><input type="submit" value="TestRest GET"></form><br></body>
</html>

控制器代码:

@RequestMapping("/springmvc")
@Controller
public class RequestMappingTest {@RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)public String testRestPut(@PathVariable("id") Integer id) {System.out.println("testRest PUT:" + id);return "success"; }@RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)public String testRestDelete(@PathVariable("id") Integer id) {System.out.println("testRest DELETE:" + id);return "success"; }@RequestMapping(value = "/testRest",method = RequestMethod.POST)public String testRestPost() {System.out.println("testRest POST");return "success"; }@RequestMapping(value = "/testRest/{id}",method = RequestMethod.GET)public String testRestGet(@PathVariable("id") Integer id) {System.out.println("testRest GET:" + id);return "success"; }
}

项目运行起来:

点GET、POST都没有问题,但你点DELETE和PUT的时候程序就报错了,报错信息如下:

报错信息提示:jsp只允许GET POST或HEAD。

这个报错其实很早之前我就遇到了,当时查了一下,总共有四种方式解决:

  1. tomcat换到7.0以及以下版本
  2. 在方法上标注@ResponseBody
  3. 请求先转给一个Controller,再返回jsp页面
  4. 在你的success页面头部设置isErrorPage属性为true

当时也确实就解决问题了,也没有深究到底是为什么,这几天大概地查了一下,网上写这个错误的人很多,但也只是给出了解决方案,并没有说到底为什么这样解决。

tomcat换到7.0以及以下版本

查阅了很多资料后,我得出一些结论,报错的信息其实很明显了,说的是jsp只允许GET、POST或HEAD,而我们使用了REST风格中的DELETE和PUT,显然就会报错了。

那么为什么把tomcat版本切换到7.0或者7.0以下的版本就不会出现这样的问题呢?

Tomcat按照JCP规范(JSP2.3版本)的规定,从Tomcat8.x版本开始,不再支持以HTTP PUT方式访问JSP页面,仅支持GET、POST和HEAD方式。

而你在控制器方法中编写的返回值是一个字符串,SpringMVC会认为这是一个jsp页面,所以报错了。
这就完美地解释了第一种解决办法为什么能够起作用,但是切换tomcat版本显然并不好。

在方法上标注@ResponseBody

刚刚说到SpringMVC会将控制器方法的返回值认为是一个jsp页面导致出错,那么你就可以在处理方法上标注@ResponseBody注解,再运行项目试一试:

运行成功,但是返回值显示到了页面上。

这就要来了解一下@ResponseBody的作用了:

@ResponseBody注解的作用是将控制器方法的返回值通过适当的转换器转换为指定的格式之后,写入到Response对象的body区,通常用来返回JSON数据或者是XML数据。
注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过Response对象输出指定格式的数据。

看到这,你是不是就明白了,你加上这个注解,它就不走视图处理器,当然也就不会跳转到jsp页面了,不跳转到jsp页面,当然就不报错了。

不过这个注解通常是用来返回数据的,如果你确实是要返回数据,这样写当然没有问题,这也是比较规范的一种写法。

请求先转给一个Controller,再返回jsp页面

而如果你仅仅就是想跳转一个jsp页面,就可以用第三种解决方法。
既然不能直接跳转到jsp页面,你就可以将请求先转给一个控制方法,再通过该控制方法跳转到jsp页面。
修改一下控制类的代码:

@RequestMapping("/springmvc")
@Controller
public class RequestMappingTest {@RequestMapping("/toSuccess")public String toSuccess() {System.out.println("toSuccess");return "success";}@RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)public String testRestPut(@PathVariable("id") Integer id) {System.out.println("testRest PUT:" + id);return "redirect:/springmvc/toSuccess"; }@RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)public String testRestDelete(@PathVariable("id") Integer id) {System.out.println("testRest DELETE:" + id);return "redirect:/springmvc/toSuccess"; }@RequestMapping(value = "/testRest",method = RequestMethod.POST)public String testRestPost() {System.out.println("testRest POST");return "success"; }
}
......

通过这样的方式,我们的DELETE和PUT请求就不会直接地去跳转jsp页面,而是先交给了toSuccess控制方法,并由该方法跳转到jsp页面。

在你的success页面头部设置isErrorPage属性为true

至于这种解决方法为什么能够成功,相信你们应该能自己知道了吧?

就是因为DELETE和PUT请求直接跳转jsp页面会出错,当你在待跳转的jsp页面中设置isErrorPage属性为true后,在跳转jsp页面时出错,而设置了isErrorPage属性的页面即为错误页面,它就这样显示出来了。

总结

综上所述,这四种解决方法其实都是在解决同一个问题,就是jsp不支持DELETE和PUT,我们要想办法在这两种请求的方式下不直接去访问jsp就行了。

但这些方法总归是有些违背自己的主观意愿,所以只有当你需要使用DELETE和PUT请求时才去使用它们,比如通过它们返回一些数据,否则就不要去用它们了,这是多此一举。

老师常常教导我们,要知其然,还要知其所以然。

SpringMVC报错:HTTP Status 405 - JSPs only permit GET POST or HEAD相关推荐

  1. HTTP Status 405 - JSPs only permit GET POST or HEAD

    HTTP Status 405 - JSPs only permit GET POST or HEAD 版本:Spring4,Tomcat8 代码如下 web.xml: HiddenHttpMetho ...

  2. Restful风格,PUT修改功能请求,表单中存在文件报错-HTTP Status 405 - Request method 'POST' not supported...

    解决方案配置如下 <!-- 配置文件上传解析器 --><bean id="multipartResolver" class="org.springfra ...

  3. HTTP Status 405 - JSPs only permit GET POST or HEAD问题的分析和解决办法

    1.出错时的代码 (1)web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xml ...

  4. SAP COR2下达工单,报错 System status APNG is active 之对策

    SAP COR2下达工单,报错 System status APNG is active 之对策 笔者发现,在项目上的SAP系统上使用事务代码COR2去release某个工单,得到如下报错信息: 这种 ...

  5. 解决执行Command报错exit status 255

    背景:go  exec.Command 以前从未遇到过err报错255的,这次算是踩了一次坑. 出现这种情况,可将命令本身组装起来在环境上直接执行(用和代码中完全一样的参数),用$?查看结果状态看是否 ...

  6. java 报错404_Javaweb工程运行报错HTTP Status 404解决办法

    最近在学习jsp和servlet,避免不了的要和tomcat打交道,但tomcat经常会出现各式各样的错误,下面是我总结的一些常见的解决方法,希望对大家有用. 1.未部署web应用 2.url输入错误 ...

  7. 关于jsp web项目,jsp页面与servlet数据不同步的解决办法(报错404、405等)即访问.jsp和访问web.xml中注册的/servlet/的区别

    报错信息: Type Status Report Message HTTP method GET is not supported by this URL Description The method ...

  8. TOMCAT报错:HTTP Status 404 -

    构建struts2工程师,tomcat报错: HTTP Status 404 - type Status report message description The requested resour ...

  9. Nginx+Tomcat负载均衡访问网页出现报错HTTP Status 400 – 错误的请求

    小故障 今天在搭建Nginx反向代理两个Tomcat站点负载均衡访问网页出现了400的网页报错. HTTP Status 400 – 错误的请求 故障原因 问题出在了nginx主配置文件中给后端tom ...

最新文章

  1. web前端——html基础笔记 NO.12{css布局模型(流动,浮动,层模型)}
  2. 长春理工大学计算机学院分数线,2021长春理工大学录取分数线-长春理工大学分数线-2021长春理工大学录取查询网址...
  3. Apache Jserv protocol
  4. 【Samba】安装与配置
  5. ML.NET Cookbook:(7)如何训练回归模型?
  6. 解决ant design vue中的modal弹框样式修改无效问题 修改modal样式无效
  7. python批量下载网页文件夹_Python的urllib模块、urllib2模块批量进行网页下载文件...
  8. Linux iptables防火墙详解(四)——配置实战
  9. Angluar编译过程中出现的TS2339问题
  10. 工序排班问题数学模型
  11. java——傻瓜电梯
  12. win10 CMD大全
  13. 使用VBA操作文件(1):使用Excel对话框
  14. stm32 hal库分析之uart
  15. html保存时出现nul,c# – 有时保存的文件只包含NUL字符
  16. 【java毕业设计】基于java+GUL的超级玛丽游戏GUL设计与实现(毕业论文+程序源码)——超级玛丽游戏
  17. 标签云TagCloud
  18. java erc 2.0_如何使用java监听Erc20Token交易
  19. 苹果cms微信对接php,苹果cmsV10微信公众号对接插件安装教程
  20. PyQt(Python+Qt)学习随笔:invisibleRootItem方法访问QTreeWidget树型部件的隐形根节点

热门文章

  1. c语言open函数打开文件方式,Linux中C语言open函数打开或创建文件详细讲解
  2. 【MCU】一种单片机节省内存的方法(补充)
  3. NPDP红宝书----前言
  4. 小程序自定义组件之插槽
  5. 如何在网页设计中正确应用色彩?
  6. Android MVC框架 - Baymax
  7. 以太坊-挣脱数字货币的枷锁
  8. 路由、中继、AP、客户端模式之间的区别
  9. 康耐视智能相机Insight与四轴,六轴工业机器人视觉引导定位配合详细方法与步骤
  10. 推荐几款界面设计神器