文章目錄
項目總體結構如下
component下配置了一個登陸攔截器;config下配置接管springMVC添加攔截;controller下:HelloController控制頁面訪問、跳轉,UserController,entity下User實體類對應數據庫內的數據表;UserRepository繼承數據庫訪問的接口。前端的那些頁面結構就不截了,無關緊要。
JPA操作
application.yaml配置
我的數據庫叫“jpa”,先自行建立好,驅動只會建立數據表不會建立數據庫。
spring:
datasource:
url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123
driver-class-name: com.mysql.cj.jdbc.Driver #8.0以上版本的mysql使用這個驅動
jpa:
hibernate:
ddl-auto: update #create是每次創建新表並清空,update是如果有表了就不變了,沒有表就創建
show-sql: true
創建實體類User
省略了import和getter、setter,自行添加。對應了數據庫中的"users"表。應用於登陸場合,只要用戶名和密碼就OK了,然後配上id。
@Entity(name="users")
public class User {
@Id //主鍵
@GeneratedValue(strategy = GenerationType.IDENTITY) //自增主鍵
private Integer id;
@Column(name ="name")
private String name;
@Column(name ="password")
private String password;
UserRepository繼承接口JpaRepository
因爲登陸時要使用用戶名到數據庫內檢索是否有對應用戶,所以新建方法findByName(),返回值類型爲User,到時候可以使用user.getPassword()來獲取檢索的密碼,並與提交的密碼進行比對,相等則登陸成功,不等則失敗。
public interface UserRepository extends JpaRepository<User,Long> {
public User findByName(String name);
}
UserController
登陸頁會將表單提交至"/check",在selectOne方法內進行判斷,成功則跳轉至主頁, 並在session中添加內容用以判斷是否登陸,用於後續的登陸攔截——未登錄則攔截;失敗則返回“login”,並注入失敗信息,繼續填寫用戶名密碼。
@Controller
public class UserController {
@Autowired
UserRepository userRepository;
@RequestMapping("/all")
public List<User> selectAll(){
List<User> userList=userRepository.findAll();
String str= JSON.toJSON(userList).toString();
return userList;
}
@PostMapping(value = "/check")
public String selectOne(@RequestParam("name") String name, @RequestParam("password") String password, HttpSession session, Map<String,Object> map){
User user = userRepository.findByName(name);
if (user==null){
map.put("msg","用戶名不存在");
System.out.println(110);
return "login";
}
String pwd = user.getPassword();
if (pwd.equals(password)) {
session.setAttribute("loginUser", name);
return "index";
}
else{
map.put("msg","用戶名密碼錯誤");
System.out.println(111);
return "login";
}
}
}
登陸失敗的截圖如下:
登陸頁使用的bootstrap的example,可以去官網自提。表單處的代碼略有修改,主要是給兩個“input”添加了name屬性,不然post出去得不到數據;以及加了一個p標籤,提示用戶名、密碼出錯。
<form class="form-signin" action="/check" method="post">
<img class="mb-4" src="/bootstrap-solid.svg" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal">請登錄</h1>
<p style="color:red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}" ></p>
<label for="inputEmail" class="sr-only">用戶名</label>
<input type="text" name="name" id="inputEmail" class="form-control" placeholder="用戶名" required="" autofocus="">
<label for="inputPassword" class="sr-only">密碼</label>
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="密碼" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">登陸</button>
<p class="mt-5 mb-3 text-muted">© 2017-2019</p>
</form>
登陸攔截
添加攔截器component.LoginInterceptor
實現接口HandlerInterceptor,判斷session是否有注入內容,如果沒有,則表示沒有登陸,那麼攔截請求並返回login頁。
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginUser");
if(user==null){
request.setAttribute("msg","沒有權限");
request.getRequestDispatcher("/login").forward(request,response);
return false;
}
else
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
springmvc配置,添加攔截器(MyMvcConfig)
spring boot2.0後WebMvcAutoConfigurationAdapter被棄用,所以繼承WebMvcConfigurationSupport這個類。攔截所有請求,除了"/login"和"/check"。
@Configuration
public class MyMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login","/check","/static/*");
super.addInterceptors(registry);
}
}
補一個小問題:中間有一次運行時一直找不到我的如CSS等靜態文件,報錯如下:
搞了很久,重啓啊、改配置啊幾乎都試過了,沒用。最後把@Configuration註釋了運行了一次,再取消註釋運行就OK了,但不知道爲什麼。