SSMPUT请求导致的400,415,500问题
最近在尝试⽤PUT⽅法的请求时⼀直产⽣400,415,500错误,弄了半天(真的是半天),尝试了各种办法,现在终于解决了,为了防⽌忘记,在此记录下
下⾯是⼀步步解决的步骤。(还有许多我略过了)如果只想看结果滑到底即可。
⼀开始遇到的是400错误,前端是这样写的
$.ajax({
type: "POST", // 这⾥必须写POST
url: "/team/" + teamId,
data: $("#myForm").serialize() + "&_method=PUT",
dataType: "json",
success: function (vo) {
if (vo.code === 200) {
window.location.href = "/pages/team/list.html?pageNum=" + pageNum + "&pageSize=" + pageSize;
} else {
alert("更新失败!" + vo.msg);
}
}
});
我先在后台 TeamController 中对应的⽅法上打断点
@ResponseBody
@RequestMapping(value = "team/{id}", method = RequestMethod.PUT)
public ResultVO<?> update(@PathVariable Integer id, Team team) {
team.setTeamId(id);// --------------------- 在这⼀⾏打断点
if (id != null && teamService.update(team)) {
return new ResultVO<>();
}
return new ResultVO<>("球队ID 不存在!", 500);
}
发现根本没有⾛到这⾥。
于是我就检查是否是 HiddenHttpMethodFilter 没有配置,然⽽ l 写的好好的
<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>
然后我按Ctrl点进 HiddenHttpMethodFilter ⾥,在⾥⾯打断点
public static final String DEFAULT_METHOD_PARAM = "_method";
private String methodParam = DEFAULT_METHOD_PARAM;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
HttpServletRequest requestToUse = request;// --------------------- 在这⼀⾏打断点
if ("POST".Method()) && Attribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
String paramValue = hodParam);// ---- (1) ----- //
if (StringUtils.hasLength(paramValue)) {
String method = UpperCase(Locale.ENGLISH);
if (ains(method)) {
requestToUse = new HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter(requestToUse, response);
}
发现它有⾛到这⾥, 但是⾛到(1)这⼀⾏的时候, paramValue 没有取到值,也就是说 request 没有 _method 的值,可是我前端有写啊!折磨了好久,把 target ⽂件夹删了重开,paramValue 竟然就能取到值了!?离谱。
但是问题没有解决,依然还是400错误。
我⼜尝试把 _method=PUT 删掉,⽤ POST 请求,这样就可以正常访问到。但是这不是我要的结果,POST 请求已经被其他⽅法占⽤了。⼀番百度,好⼏⼈说添加⼀⾏ contentType:"application/json" ,于是我就添加⼀⾏
$.ajax({
type: "POST", // 这⾥必须写POST
url: "/team/" + teamId,
data: $("#myForm").serialize() + "&_method=PUT",
dataType: "json",
contentType: "multipart/form-data",  // 添加了这⼀⾏
success: function (vo) {
if (vo.code === 200) {
window.location.href = "/pages/team/list.html?pageNum=" + pageNum + "&pageSize=" + pageSize;
} else {
alert("更新失败!" + vo.msg);
}
发送ajax请求的步骤
}
});
这回不是400了,变成了415错误。害,继续搞呗。
继续百度,有⼈说后台把 Team 对象改成⼀个map集合,像这样:@RequestBody Map<String, String> map,不出意料,改了之后没有任何作⽤。
我尝试把 type 由 “POST” 改成 “PUT” ,像这样
$.ajax({
type: "PUT",
url: "/team/" + teamId,
data: $("#myForm").serialize(),
dataType: "json",
// contentType: "multipart/form-data",
success: function (vo) {
if (vo.code === 200) {
window.location.href = "/pages/team/list.html?pageNum=" + pageNum + "&pageSize=" + pageSize;
} else {
alert("更新失败!" + vo.msg);
}
}
});
这样后台只取到了 id, Team ⾥的信息没有取到。
我⼜怀疑是版本的问题。我将 target 清除,改成使⽤ maven 的 tomcat 插件启动(之前是⽤ tomcat 9.0.52),插件是 7 的版本。然⽽,很不幸,问题还是没有解决(我要吐槽⼀下这个tomcat插件,连页⾯都进不去,⽤下载的tomcat 9 就没问题)。
后来看到⼀篇说 JSON 的属性也要加上双引号像这样 { “aaa”: “bbb” },⽽不是 { aaa: "bbb" },我就想,把 data 换成 JSON 格式试试,竟然就真的可以了!太奇怪了吧。
$.ajax({
type: "POST", // 这⾥必须写POST
url: "/team/" + teamId,
data: {
"teamId":$teamId.val(),
"teamName":$teamName.val(),
"chineseName":$chineseName.val(),
"coach":$coach.val(),
"stadium":$stadium.val(),
"location":$location.val(),
"createTime":$createTime.val(),
"area":$area.val(),
"_method": "PUT"// 不要忘记写这⼀⾏,将来能把 POST 改成 PUT
},
dataType: "json",
// contentType: "multipart/form-data",
success: function (vo) {
if (vo.code === 200) {
window.location.href = "/pages/team/list.html?pageNum=" + pageNum + "&pageSize=" + pageSize;
} else {
alert("更新失败!" + vo.msg);
}
}
});
然⽽事情还没完,我把前端改成原先的模样,他竟然⼜可以了!看来不是前端的问题。那究竟是哪⾥的问题呢?⾸先排除是target的问题,因为前⾯删掉重新⽣成过了。应该是我哪⾥改对了⼜忘了。。。
后来,第⼆天,我⼜在另⼀个模块遇到了400错误。这回我把 ajax 的 data 改成 JSON 格式也⽆济于事了,之前的各种办法试了也没⽤,就卡死在这⾥了。
⼜过了⼀天,我想再看看是什么原因。既然⼀个可以⽤,另⼀个不可以,那对⽐⼀下两者之间有什么不同不就⾏了吗。⾸先前端的 ajax 都是⼀样的,检查 Controller,注解也都⼀样,没有缺失什么。
我⼜把⽬光转向了 pojo 类:
// 这个是可以⽤的
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date createTime;
// 这个会报 400 错误
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday;
两个 pojo 类都有 Date 类型的属性,但是其中⼀个少了@DateTimeFormat(pattern = "yyyy-MM-dd")注解。马上安排,我加上注解之后,果然可以正常运⾏了。
由此可见,@DateTimeFormat(pattern = "yyyy-MM-dd")注解是将浏览器发送到后台的数据进⾏打包的,如果没有的话在接受数据时就会发⽣问题。
⽽@JsonFormat(pattern = "yyyy-MM-dd")是将后台要发送给前端的数据进⾏打包的,如果没有这个注解前端显⽰就会有问题。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。