今天的错误比较常规,虽然一开始没有想到,但是后来还是很成功的解决了问题,出现该错误的原因有很多,这里只列举我出现的情况和解决方法,以后有新的解决方法也会回来更新本博客🧡
这个错误说实在话啊说好找也好找,说不好找也不好找
在控制台报的错:
在页面上:
首先,讲讲我想干什么,是如何报错的,对号入座,如果大家发现和我的一致那就继续看下去吧,如果不一致,也请另请高明~
🙋♀️我想做的是使用SSM实现用户登录权限验证的功能,具体我想实现:
1️⃣只有登录后的用户才能访问系统中的主页
2️⃣没有登陆系统而直接访问主页,则会被拦截器拦截,并转发到登录界面,同时在登录界面中给出提示信息。
3️⃣如果用户名和密码错误,也会在登录界面给出登录信息
前面都是顺风顺水,下面是我的LoginController.java
package com.xmonster.controller;
import com.xmonster.pojo.Books;
import com.xmonster.pojo.User;
import com.xmonster.service.BookService;
import com.xmonster.service.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
@Controller
public class LoginController {
private UserServiceImpl userService;
public UserServiceImpl getUserService() {
return userService;
}
@Autowired
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
// 向用户登陆页面跳转
@RequestMapping(value = "/tologin")
public String toLogin(){
return "login";
}
//用户登录
@RequestMapping(value = "/login",method = RequestMethod.POST)
public String login(User user, Model model, HttpSession session, HttpServletRequest request){
String userName = user.getName();
String userPwd = user.getPwd();
System.out.println(userName+userPwd);
if(userName != null && userPwd != null){
List<User> userList = userService.selectAllUser();
for (User user1 : userList) {
if(userName.equals(user1.getName()) && userPwd.equals(user1.getPwd())){
session.setAttribute("USER_SESSION",user);
return "redirect:/book/allBook";
}
}
}
model.addAttribute("msg", "用户名或密码错误,请检查!");
return "login";
}
//退出登录
@RequestMapping(value = "/logout")
public String logOut(HttpSession session){
session.invalidate();
return "redirect:/login";
}
}
拦截器:下面可以看到我有很多的输出,那是在后面为了测试做的,可以忽略🤠
package com.xmonster.interceptor;
import com.xmonster.pojo.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
if(requestURI.indexOf("/login")>=0){
System.out.println("1通行!1");
return true;
}
HttpSession session = request.getSession();
User user = (User)session.getAttribute("USER_SESSION");
if(user!=null){
System.out.println("2通行!2");
return true;
}
System.out.println("未登录,不通行!!");
request.setAttribute("msg", "你还没登录,请先登录!");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
html我就只展示重点的代码内容,其他不展示,login.jsp:
<div class="container" id="login">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="login">
<h1>Login</h1>
<%-- 如果用户都填完信息之后后台检测不到该用户--%>
${msg};
<!-- Loging form -->
<form action="${pageContext.request.contextPath}/login" method="post">
<div class="form-group">
<input type="text" class="form-control" id="username" name="name" placeholder="Enter username">
<span id="userInfo"></span>
</div>
<div class="form-group">
<input type="password" class="form-control" id="pwd" name="pwd" placeholder="Password">
<span id="pwdInfo"></span>
</div>
<div class="form-check">
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
<label class="form-check-label">Remember me</label>
<label class="forgot-password"><a href="#">Forgot Password?</a></label>
</div>
<br>
<button type="submit" class="btn btn-lg btn-block btn-success">Sign in</button>
</form>
<!-- End Loging form -->
</div>
</div>
</div>
</div>
问题出在哪?
首先,在我们请求一个页面的时候,默认都是GET方法请求的,像这样:
当我请求/logout时候:
到这里其实就可以看出来了,在我请求了/logout的时候,按照上面的代码我们知道他肯定会重定向到/login,但是,我们的/login增加了这段代码:
而且现在就有一个问题
那就是为什么/tologin可以请求到login.jsp,但是/logout重定向到login.jsp就会报405的u错误呢?
为此我特意将/tologin的返回值也设置成了重定向的形式,结果证明也发生了405错误,那么问题就很明显了💥💥💥
问题就出在了method = RequestMethod.POST
💜
回顾method元素,它声明了HTTP请求方法的类型,所有的处理方法会处理同一个URL进来的请求,但是具体要看指定的HTTP类型来决定哪个方法处理,显然,我一开始使用了POST方法在/login的请求中,也就是说只有你这个方法是POST才可以调用我的/login请求,但是像/logout它本身就是GET请求,所以不匹配,不一致,导致405错误的发生。