Springboot 利用servlet filter拦截器+jsp实现用户名密码登录界面

springboot中大家比较常用的是HandlerInterceptor接口,可是我不太习惯,习惯了使用servlet下的filter接口,以及jsp网页形式,所以不想改习惯。我一直觉得,编程语言这东西,各种语言以及语法都各有优劣,好坏不好乱下定义,但是最重要的,可能还是根据你的习惯来选择吧。话不多说,做一下记录吧。数据库的连接配置就不多说了,我用的mysql数据库。
大概分为七步走:

  • 1.修改springboot的配置参数,包括jsp以及数据库的一些配置。
  • 2.创建一个实体类,取用用户名密码。创建一个数据库,并且创建一张表格,用来存储用户名、密码。
  • 3.添加一个springdata JPA来从数据库中查询匹配结果,用作用户名密码的匹配。
  • 4.修改启动项中的注解,来注入servlet的使用。启动项一般都是以XXXApplication.java。
  • 5.创建login.jsp登录页面,和index.jsp结果显示页面。
  • 6.创建LoginController和IndexController,在此进行用户名以及密码的进行匹配,根据结果来控制页面跳转。
  • 7.添加filter拦截器,匹配是否登录成功。
    先看看我的目录架构
    在这里插入图片描述
    再看一样我的pom.xml。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

一、springboot的参数配置

我自行创建了一个appliacation.yml的配置文件
内容如下:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root

  jpa:
    #本地sql方言
    database: mysql
    show-sql: true #用来在控制台输出JPA自动生成的sql语句
    hibernate:
      ddl-auto: update #需要手动创建数据库,除此,数据表之类的无需手动创建。
  mvc:
    view:
      prefix: /WEB-INF/jsp/
      suffix: .jsp

二、创建一个实体类,并创建一个数据库,用来存储用户名密码

package com.example.demo.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import com.alibaba.fastjson.annotation.JSONField;

@Entity//表示这是一个和数据库相关联的类
@Table(name="t_user")
public class UserEntity implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Id//主键
	@GeneratedValue//自增长
	private Long id;
	@Column(name = "t_name")
	private String name;
	@Column(name = "t_pwd")
	private String pwd;
	
    public UserEntity()
    {
    }
    public UserEntity(String name, int age,Date createTime,String pwd)
    {
        this.name = name;
        this.pwd=pwd;
    }
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id=id;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name=name;
	}
	
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd=pwd;
	}
}

上面就是创建了一个实体类。
然后,需要手动创建一个叫test的数据库,或者你在配置文件applicaiton.yml中自行命名的数据库名称,名称要对应上,除此,数据表之类的无需手动创建,会根据实体类自行创建。
然后在数据库中存入一些用户名密码,数据库的操作方法我就不多说了。用mysql的话可以用navicat软件进行管理。

三、添加一个SPRINGDATA JPA使用数据库

package com.example.demo.jpa;

import java.io.Serializable;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;

import com.example.demo.entity.UserEntity;

//数据访问接口
public interface UserJPA extends JpaRepository<UserEntity, Long>,
					JpaSpecificationExecutor<UserEntity>,Serializable{
}

对,里面不需要东西,因为我们会使用到的数据库函数,都是他自带的一些函数,我们会用到findOne(),函数,就包含在JpaSpecificationExecutor中。

四、修改启动项,添加对servlet的支持

package com.example.demo;

import java.util.ArrayList;
import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

@SpringBootApplication
//添加下面这个注释,然后就可以在springboot中使用servlet了
@ServletComponentScan

public class DemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}

重点在@ServletComponentScan,这个注释,很简单,就添加一个这个就行。

五、创建login.jsp和index.jsp

这一步本身很简单,不过需要注意,在springboot中默认是没有给你预留放jsp文件的地方的,这个文件目录需要自己创建,并且在applicaition.yml中标志好。我的目录在最前面那张图中已经展示了。
login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>login.jsp</title>
</head>
<body>
	<form method="get" action="/user/login">
		用户名:<input type="text" name="name"/><br/>
		密码:<input type="text" name="pwd"/>
		<input type="submit" value="登录">
	</form>
</body>
</html>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index.jsp</title>
</head>
<body>
	您未通过登录界面,直接访问到该网页!
</body>
</html>

login.jsp的作用是作为登录界面用。index.jsp没啥用处。

六、创建LoginController和IndexController两个跳转的管理类

在这一部分,就是核心部分,就是进行用户名密码的匹配,并根据结果进行跳转。懒得废话,直接贴代码:
LoginController

package com.example.demo.controller;

import java.util.Optional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.entity.UserEntity;
import com.example.demo.jpa.UserJPA;

@RestController
@RequestMapping(value = "/user")
public class LoginController {
    @Autowired
    private UserJPA UserJPA;
	@RequestMapping(value = "/login",produces = "text/plain;charset=utf-8")//设置输出到页面的中文位utf-8,不然会出现乱码
	public String login(UserEntity user,HttpServletRequest request) {
		boolean flag=true;
		String result= "登录成功";
        //匿名内部类
        /**
         * 自定义查询条件
         *      1.实现Specification接口(提供泛型:查询的对象类型)
         *      2.实现toPredicate方法(构造查询条件)
         *      3.需要借助方法参数中的两个参数(
         *          root:获取需要查询的对象属性
         *          CriteriaBuilder:构造查询条件的,内部封装了很多的查询条件(模糊匹配,精准匹配)
         *       )
         *  案例:根据客户名称查询,查询客户名为传智播客的客户
         *          查询条件
         *              1.查询方式
         *                  cb对象
         *              2.比较的属性名称
         *                  root对象
         *
         */
        Specification<UserEntity> spec = new Specification<UserEntity>() {

			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> query,
					CriteriaBuilder criteriaBuilder) {
    			//添加限制条件,root查询的是属性名,不是表的字段名
    			Predicate p1=criteriaBuilder.equal(root.get("name"),user.getName());
    			//把Predicate应用到CriteriaQuery中去,因为还可以给CriteriaQuery添加其他的功能,比如排序、分组啥的  
    			query.where(p1);
    			return query.getRestriction();
				// TODO Auto-generated method stub
			}
        };
		Optional<UserEntity> find = UserJPA.findOne(spec);

		if(find==null) {
			flag=false;
			result="用户不存在,登录失败";
		}else if(!find.get().getPwd().equals(user.getPwd())) {
			flag=false;
			result="用户密码不相符,登录失败";
		}
		//登录成功
		if(flag) {
			//将用户写入session
			request.getSession().setAttribute("session_user", find.get());
		}
		
		return result;
	}

}

IndexController

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/user")
public class IndexController {
	/**
	 * 初始化登录页面
	 * @return
	 */
	@RequestMapping(value = "/login_view",method = RequestMethod.GET)
	public String login_view() {
		return "login";
	}
	
	@RequestMapping(value = "/index",method = RequestMethod.GET)
	public String index() {
		return "index";
	}
}

七、添加过滤器,实现过滤。

在这里,我将要servlet的过滤器filter,在springboot中不能直接创建filter过滤器,需要先创建普通的class类,然后修改成filter,当然,直接从别处复制应该也可以。

package com.example.demo.controller;

import java.util.Optional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.entity.UserEntity;
import com.example.demo.jpa.UserJPA;

@RestController
@RequestMapping(value = "/user")
public class LoginController {
    @Autowired
    private UserJPA UserJPA;
	@RequestMapping(value = "/login",produces = "text/plain;charset=utf-8")//设置输出到页面的中文位utf-8,不然会出现乱码
	public String login(UserEntity user,HttpServletRequest request) {
		boolean flag=true;
		String result= "登录成功";
        //匿名内部类
        /**
         * 自定义查询条件
         *      1.实现Specification接口(提供泛型:查询的对象类型)
         *      2.实现toPredicate方法(构造查询条件)
         *      3.需要借助方法参数中的两个参数(
         *          root:获取需要查询的对象属性
         *          CriteriaBuilder:构造查询条件的,内部封装了很多的查询条件(模糊匹配,精准匹配)
         *       )
         *  案例:根据客户名称查询,查询客户名为传智播客的客户
         *          查询条件
         *              1.查询方式
         *                  cb对象
         *              2.比较的属性名称
         *                  root对象
         *
         */
        Specification<UserEntity> spec = new Specification<UserEntity>() {

			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> query,
					CriteriaBuilder criteriaBuilder) {
    			//添加限制条件,root查询的是属性名,不是表的字段名
    			Predicate p1=criteriaBuilder.equal(root.get("name"),user.getName());
    			//把Predicate应用到CriteriaQuery中去,因为还可以给CriteriaQuery添加其他的功能,比如排序、分组啥的  
    			query.where(p1);
    			return query.getRestriction();
				// TODO Auto-generated method stub
			}
        };
		Optional<UserEntity> find = UserJPA.findOne(spec);

		if(find==null) {
			flag=false;
			result="用户不存在,登录失败";
		}else if(!find.get().getPwd().equals(user.getPwd())) {
			flag=false;
			result="用户密码不相符,登录失败";
		}
		//登录成功
		if(flag) {
			//将用户写入session
			request.getSession().setAttribute("session_user", find.get());
		}
		
		return result;
	}

}

测试结果

在运行之后,登录http://127.0.0.1:8080/user/login_view会出现这样如下界面:
在这里插入图片描述
输入你之前存储好的用户名,密码。如果正确,页面会变为如下内容,注意,这时候页面未跳转,只是内容变化了。
在这里插入图片描述
如果这时候你把地址改成,http://127.0.0.1:8080/user/index,这时候会变成如下界面,这个是绕过了用户名密码以后的直接登录。
在这里插入图片描述

发布了45 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/baidu_31788709/article/details/103773628