010 springboot整合mybatis-plus 登录页面和首页不拦截

文章目录

    • customer.sql
    • ConfigRegistCenter.java
    • CustomerController.java
    • Customer.java
    • LoginCustomer.java
    • JwtInterceptor.java
    • CustomerMapper.java
    • ICustomerService.java
    • CustomerServiceImpl.java
    • JwtUtil.java
    • ServerResult.java
    • ServletInitializer.java
    • SpringbootLoginApplication.java
    • application.yaml
    • css_04_首页.css
    • css_11_login.css
    • js_02_登录验证.js
    • index.html
    • login.html
    • pom.xml

customer.sql


-- ----------------------------
-- Table structure for customer
-- ----------------------------
DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer`  (
  `customer_id` int(0) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
  `customer_pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户密码',
  `customer_telno` bigint(0) NOT NULL COMMENT '用户电话',
  `customer_status` int(0) NULL DEFAULT NULL COMMENT '用户状态',
  `customer_create_date` date NULL DEFAULT NULL COMMENT '注册时间',
  `customer_head_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '头像',
  `customer_update_date` date NULL DEFAULT NULL COMMENT '更改时间',
  `other1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `other2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `custom_cteate_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `custom_update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`customer_id`) USING BTREE,
  UNIQUE INDEX `customertel_index`(`customer_telno`) USING BTREE COMMENT '用户手机号'
) ENGINE = InnoDB AUTO_INCREMENT = 111 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of customer
-- ----------------------------
INSERT INTO `customer` VALUES (1, 'zhang', 'zhang1023', 14506764314, 1, '2001-06-17', 'zhang.png', NULL, NULL, NULL, NULL, NULL);



ConfigRegistCenter.java


package com.example.config;

import com.example.interceptor.JwtInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration //将当前类注入到Spring容器中
@EnableWebMvc
public class ConfigRegistCenter implements WebMvcConfigurer {
    //注册拦截器

    public void addInterceptors(InterceptorRegistry registry){

        // "/" 项目根目录(http://localhost:80/app)

        registry.addInterceptor(new JwtInterceptor()).addPathPatterns("/**") //所有资源,包括静态资源
                .excludePathPatterns("/static/**")
                .excludePathPatterns("/customer/login");

    }



    // 静态资源配置
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("/","classpath:webapp/");
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }



}




CustomerController.java


package com.example.controller;


import com.example.entity.Customer;
import com.example.service.ICustomerService;
import com.example.util.ServerResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author dd
 * @since 2024-04-10
 */
@Controller
@RequestMapping("customer")
public class CustomerController {
    @Autowired
    private ICustomerService iCustomerService;

    @GetMapping("{customerId}")
    @ResponseBody
    public Customer getById(@PathVariable("customerId") Integer customerId){
        Customer customer = iCustomerService.getById(customerId);
        return customer;
    }


//    @PostMapping("login")
//    public ModelAndView login(String customerName, String customerPwd){
//
//        ServerResult result = iCustomerService.login(customerName, customerPwd);
//        ModelAndView mav = new ModelAndView();
//        if(result.getCode() == 200){
//            mav.addObject("result",result);
//            mav.setViewName("login2");
//        }else{
//            mav.addObject("result",result);
//            mav.setViewName("login");
//        }
//        return mav;
//
//
//    }



    @PostMapping("login")
    @ResponseBody
    public ServerResult login(String customerName, String customerPwd){

        System.out.println("contoller层"+customerName+customerPwd);
        ServerResult result = iCustomerService.login(customerName,customerPwd);
        System.out.println(result);
        return result;
    }

}




Customer.java


package com.example.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * <p>
 * 
 * </p>
 *
 * @author dd
 * @since 2024-04-10
 */
public class Customer implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 用户id
     */
    @TableId(value = "customer_id", type = IdType.AUTO)
    private Integer customerId;

    /**
     * 用户名
     */
    private String customerName;

    /**
     * 用户密码
     */
    private String customerPwd;

    /**
     * 用户电话
     */
    private Long customerTelno;

    /**
     * 用户状态
     */
    private Integer customerStatus;

    /**
     * 注册时间
     */
    private LocalDate customerCreateDate;

    /**
     * 头像
     */
    private String customerHeadImg;

    /**
     * 更改时间
     */
    private LocalDate customerUpdateDate;

    private String other1;

    private String other2;

    /**
     * 创建时间
     */
    private LocalDateTime customCteateTime;

    /**
     * 更新时间
     */
    private LocalDateTime customUpdateTime;

    public Integer getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }
    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
    public String getCustomerPwd() {
        return customerPwd;
    }

    public void setCustomerPwd(String customerPwd) {
        this.customerPwd = customerPwd;
    }
    public Long getCustomerTelno() {
        return customerTelno;
    }

    public void setCustomerTelno(Long customerTelno) {
        this.customerTelno = customerTelno;
    }
    public Integer getCustomerStatus() {
        return customerStatus;
    }

    public void setCustomerStatus(Integer customerStatus) {
        this.customerStatus = customerStatus;
    }
    public LocalDate getCustomerCreateDate() {
        return customerCreateDate;
    }

    public void setCustomerCreateDate(LocalDate customerCreateDate) {
        this.customerCreateDate = customerCreateDate;
    }
    public String getCustomerHeadImg() {
        return customerHeadImg;
    }

    public void setCustomerHeadImg(String customerHeadImg) {
        this.customerHeadImg = customerHeadImg;
    }
    public LocalDate getCustomerUpdateDate() {
        return customerUpdateDate;
    }

    public void setCustomerUpdateDate(LocalDate customerUpdateDate) {
        this.customerUpdateDate = customerUpdateDate;
    }
    public String getOther1() {
        return other1;
    }

    public void setOther1(String other1) {
        this.other1 = other1;
    }
    public String getOther2() {
        return other2;
    }

    public void setOther2(String other2) {
        this.other2 = other2;
    }
    public LocalDateTime getCustomCteateTime() {
        return customCteateTime;
    }

    public void setCustomCteateTime(LocalDateTime customCteateTime) {
        this.customCteateTime = customCteateTime;
    }
    public LocalDateTime getCustomUpdateTime() {
        return customUpdateTime;
    }

    public void setCustomUpdateTime(LocalDateTime customUpdateTime) {
        this.customUpdateTime = customUpdateTime;
    }

    @Override
    public String toString() {
        return "Customer{" +
            "customerId=" + customerId +
            ", customerName=" + customerName +
            ", customerPwd=" + customerPwd +
            ", customerTelno=" + customerTelno +
            ", customerStatus=" + customerStatus +
            ", customerCreateDate=" + customerCreateDate +
            ", customerHeadImg=" + customerHeadImg +
            ", customerUpdateDate=" + customerUpdateDate +
            ", other1=" + other1 +
            ", other2=" + other2 +
            ", customCteateTime=" + customCteateTime +
            ", customUpdateTime=" + customUpdateTime +
        "}";
    }
}




LoginCustomer.java


package com.example.entity;

public class LoginCustomer {
    private Integer customerId;
    private String customerName;


    public LoginCustomer() {
    }

    public LoginCustomer(Integer customerId, String customerName) {
        this.customerId = customerId;
        this.customerName = customerName;
    }


    public Integer getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
}




JwtInterceptor.java


package com.example.interceptor;

import com.example.util.JwtUtil;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录检查拦截器
 * 被拦截下来的URL:
 * 1.获得token
 * 2.check token
 */
public class JwtInterceptor implements HandlerInterceptor {

    //在访问前拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("登录检查拦截器正在拦截URL>>>"+request.getRequestURI());
        //跨域请求会首先发一个option请求,直接返回正常状态并放行
        //if(request.getMethod().equals("OPTION"))
            //return true;
        //1.获得token
        String token = request.getHeader("token");
        if(token == null || token.equals("")){
            System.out.println("登录检查拦截器正在拦截,没有获得到token");
            //跳转到登录页面
            response.sendRedirect(request.getContextPath()+"/static/login.html");
            return false;
        }else {//2.check token
            System.out.println("登录检查拦截器正在拦截,获得到的token:"+token);
            if (JwtUtil.checkToken(token)){//有效token
                return true;
            }else {
                System.out.println("被拦截了,无效token");
                return false;
            }
        }

//        if(token != null){
//            if(JwtUtil.checkToken(token))
//                return true;//token有效
//        }
//        return false;

    }


}





CustomerMapper.java


package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.Customer;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author dd
 * @since 2024-04-10
 */
public interface CustomerMapper extends BaseMapper<Customer> {

}




ICustomerService.java



package com.example.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.Customer;
import com.example.util.ServerResult;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author dd
 * @since 2024-04-10
 */
public interface ICustomerService extends IService<Customer> {


    public ServerResult login(String customerName, String customerPwd);

}



CustomerServiceImpl.java


package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.Customer;
import com.example.mapper.CustomerMapper;
import com.example.service.ICustomerService;
import com.example.util.JwtUtil;
import com.example.util.ServerResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dd
 * @since 2024-04-10
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer>   implements ICustomerService {

    @Autowired
    private CustomerMapper customerMapper;

    @Override
    public ServerResult login(String customerName, String customerPwd){

        System.out.println("seivice层"+customerName+customerPwd);

        QueryWrapper<Customer> wrapper = new QueryWrapper<>();
        wrapper.eq("customer_name",customerName).eq("customer_pwd",customerPwd);
        Customer customer = customerMapper.selectOne(wrapper);
        if(customer != null){
            System.out.println("service层customer 登录");
            String token = JwtUtil.createToken(customer.getCustomerId(),customer.getCustomerName());
            return ServerResult.loginSuccess(token);
        }
        return ServerResult.loginFail("用户登录失败");
    }

}




JwtUtil.java


package com.example.util;


import com.example.entity.LoginCustomer;
import io.jsonwebtoken.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    private static final String jwtToken = "dahkgag7*$";
    private static long expireTime = 1000*60*60*24;



    /**
     * 创建新token
     * @param customerId 用户id
     * @param customerName
     * @return
     */
    public static String createToken(Integer customerId,String customerName){

        Map<String,Object> claims = new HashMap<>();
        claims.put("customerId",customerId);
        claims.put("customerName",customerName);

        System.out.println("创建token"+customerId);
        System.out.println("创建token"+customerName);

        JwtBuilder jwtBuilder = Jwts.builder().signWith(SignatureAlgorithm.HS256,jwtToken)//签发算法(head部分),秘钥为jwtToken
                .setClaims(claims)//body数据,要唯一,自行设。payload部分数据 //1.(customerId,customerName)--token
                .setIssuedAt(new Date())//设置签发时间:保证每次生成的token不同
                .setExpiration(new Date(System.currentTimeMillis()+expireTime));//一天的有效时间

        String token = jwtBuilder.compact();


        return token;
    }

    //验证token是否有效

    /**
     * 验证token是否有效
     * @param token 客户端携带的token
     * @return 返回是否有效
     */
    //2.验证token是否过期
    public static boolean checkToken(String token){
        if(token != null && !token.equals("")){
            try {
                Jwt parse = Jwts.parser().setSigningKey(jwtToken).parseClaimsJws(token);
                return true;
            }catch (ExpiredJwtException e){
                System.out.println("token已经过期了");
                return false;
            } catch (Exception e) {
                System.out.println("无效的token");
                return false;
            }
        }else
            return false;
    }




    /**
     * 解析token中的用户数据
     * @param token 客户端携带的token
     * @return 返回登录用户信息(customerIs)
     */
    public static LoginCustomer parseToken(String token){

        if(token != null && !token.equals("")) {
            try {
                Jwt parse = Jwts.parser().setSigningKey(jwtToken).parseClaimsJws(token);
                Map<String,Object> map = (Map<String, Object>)parse.getBody();
                if(map != null){
                    Integer custId = (Integer)map.get("customerId");//注意,此处的key 要与当初绑定进去的key一致
                    String custName = (String)map.get("customerName");//注意,此处的key 要与当初绑定进去的key一致

                    LoginCustomer loginCustomer = new LoginCustomer(custId,custName);
                    System.out.println("获得到的登录用户的信息是:" + loginCustomer);
                    return loginCustomer;
                }else{
                    System.out.println("获得到的登录用户的信息失败");
                    return null;
                }
            } catch (Exception e){
                e.printStackTrace();
                return null;
            }


        }else
            return null;

    }





}




ServerResult.java



package com.example.util;

public class ServerResult {
    private int code;
    private String msg;

    private Object data;



    public static ServerResult getSuccess(Object data){
        return new ServerResult(200,"查询成功",data);
    }

    public static ServerResult getFail(Object data){
        return new ServerResult(201,"查询失败",data);
    }


    /**
     * 添加、删除、修改的成功
     * @param data
     * @return
     */

    public static ServerResult updateSuccess(Object data){
        return new ServerResult(200,"处理成功",data);
    }


    /**
     * 添加、删除、修改的失败
     * @param data
     * @return
     */
    public static ServerResult updateFail(Object data){
        return new ServerResult(201,"处理失败",data);
    }


    public static ServerResult loginSuccess(Object data){
        return new ServerResult(200,"登录成功",data);
    }

    public static ServerResult loginFail(Object data){
        return new ServerResult(201,"登录失败",data);
    }






    public ServerResult() {
    }


    public ServerResult(int code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }


    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }


    @Override
    public String toString() {
        return "ServerResult{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}



ServletInitializer.java


package com.example;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringbootLoginApplication.class);
    }

}




SpringbootLoginApplication.java


package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mapper")
public class SpringbootLoginApplication {

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

}




application.yaml


server:
  servlet:
    context-path: /app
  port: 80

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/dicts?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
  mvc:
    view:
      prefix: / #前缀
      suffix: .jsp #后缀
    hiddenmethod:
      filter:
        enabled: true # 支持表单 method 转换

logging:
  file:
    path: d://logger #日志记录
  level:
    com.example: debug




css_04_首页.css


*{
    margin: 0;
    padding: 0;
}
/* =======================头部======================= */
.header{
    width: 85%;   /*  %: 父元素(父标签的百分比)*/
    height: 58px;
    /* background-color: aquamarine; */
    min-width: 1000px;
    margin: 0 auto;  /*容器水平居中*/
}

/* =======================logo部分 =======================*/
.header .logo{
    width: 15%;
    height: 33px;
    /* background-color: #fa8072; */
    float: left;   /*不换行*/
    margin-top: 12px;  /*距离顶部间距*/
}

.header .logo a{  /*行内元素不能设置宽高度,转换成 inline-block / block*/
    display: inline-block;
    width: 100%;
    height: 33px;
    background: url(../images/header-small-sprites3.png) no-repeat 0 -25px;
    background-size: 125px;
}




/*======================= 导航部分 =======================*/
.header .nav{
    width: 35%;
    height: 100%;
    /* background-color: skyblue; */
    float: left;
    min-width: 450px;
}

/* 1.设置UL 宽高度 : 100%
2.小黑点去掉UL
3.Li 不换行 : float :left 
4.设置每个li 宽高度
5.A 超链接宽高度 = li 宽高度
6.设置a超链接文字的大小,居中,下划线
7.鼠标悬浮样式修改 a:hover */

.nav .head-nav{
  width: 100%;
  height: 100%;
  /* background-color: burlywood; */
  list-style: none;  /*小黑点去掉UL*/
}

.head-nav li{
    float: left;  /*不换行 */
    height: 100%;
    width: 80px;
   /* border-right: 1px dotted white;  solid : 实线 , dashed: 虚线 , dotted : 圆点*/
}

.head-nav li a{
    display: inline-block;
    width: 100%;
    height: 100%;
    color: rgb(78, 78, 78);
    text-decoration: none; /*超链接下划线去除*/
    font-size: 13px;
    text-align: center;
    line-height: 58px;
}
.head-nav li a:hover{  /*鼠标悬浮样式修改 */
    background-color: rgba(230, 69, 102, 0.1);
    color: rgb(78, 78, 78);
    border-bottom: 3px solid rgba(230, 69, 102, 0.1)
}

.head-nav .first-item{  /*第一个li ,首页*/
    background-color: rgba(230, 69, 102, 0.1);
    color: rgb(78, 78, 78);
}
.head-nav .first-item:hover{ /*第一个li ,首页,鼠标悬浮不变*/
    background-color: rgba(230, 69, 102, 0.1);
    color: rgb(78, 78, 78);
    border-bottom:none;
}


/* =====================搜索区域=========================== */
.search{
    width: 25%;
    height: 100%;
      /* background-color: yellow;  */
    float: left;
    min-width: 260px;
}


.search form{
    width: 100%;
    height: 30px;
    /* background-color: aqua; */
    margin-top: 12px;
   
}
/* 搜索框 */
.search form .search-kw{
    width: 180px;
    height: 100%;
    border: 1px solid rgba(230, 69, 102, 0.1);
    border-radius: 4px;
   outline: none; /*点击输入框的内边框 取消*/
   padding-left: 10px;/*内部的文字 左间距 : 左内间距*/
   color:  rgb(108, 108, 108);
}

/* 搜索按钮 */
.search .search-btn{
    width: 60px;
    height: 30px;
    background-color: rgba(230, 69, 102, 0.1);
    font-size: 12px;
    color: rgb(78, 78, 78);
    border: none;
    cursor: pointer ;  /*鼠标悬浮上去 是小手链接形状*/
    border-radius: 4px;
}

/*======================= 登录区域======================= */
.header  .login{
    
    width: 13%;
    height: 100%;
    /* background-color: yellow; */
    float: right;
}

.login a{
    display: inline-block;
    width: 60px;
    height: 30px;
    background-color: rgba(230, 69, 102, 0.1);
    margin-top: 14px;  /*上间距*/
    border-radius: 4px;  /*圆角*/
    text-decoration: none;
    color: rgb(78, 78, 78);
    font-size: 12px;
    text-align: center;
    line-height: 30px;
}

.login a:hover{  /*:hover  鼠标悬浮*/
    /* background-color:white;
    color: rgba(230, 69, 102, 0.1); */
    /* border: 1px solid rgba(230, 69, 102, 0.1); */
    font-weight: bold;
}


/* ==========================banner======================== */
.banner{
    width: 100%;
    height: 400px;
    /* background-color: salmon; */
}

.banner img{
    width: 100%;
    height: 100%;
}

/*    =======================  热门商品==================  */
.pro-title{
    width: 100%;
    height: 80px;
    /* background-color: salmon; */
    text-align: center;
    line-height: 80px;
    font-size: 28px;
}
/* 商品列表 */
.pro-list{
    width: 85%;
    height: 660px;
    /* background-color: skyblue;  */
   margin:  0 auto; /* 容器居中 */
}

.pro-list ul{
    width: 100%;
    height:  100%;
    list-style: none;
}

.pro-list ul li{
    width: 230px;
    height: 320px;
    /* border: 3px solid salmon; */
    float: left;  /* 不换行 */
    margin-right: 30px;
    margin-bottom: 10px;

}

.pro-list ul li img{
    width: 160px;
    height: 160px;
    /* background-color: sandybrown; */
}

.pro-list ul  .pro-name{
    width: 190px;
    height: 48px;
    /* background-color: chartreuse; */
    margin-left: 20px;
    font-size: 13px;
    color: darkgrey;
    text-align: center;
}
.pro-name-a{
    text-decoration: none;
}
.pro-list ul  .pro-price{
    width: 190px;
    height: 18px;
    /* background-color: antiquewhite; */
    margin-left: 20px;
    margin-top: 10px;
    text-align: center;
    color: rgba(230, 69, 101, 0.591);

}

.pro-price i{
    vertical-align: middle;
    font-size: 12px;
    font-weight: 700;
    font-family: MicrosoftYahei-regular,Arial,Helvetica,sans-serif;
}



css_11_login.css



*{
    margin:0;
    padding: 0;
}

body{
    background : rgba(230, 69, 102, 0.1); /*背景图片*/
}

.login_form{
    width: 440px;
    height: 350px;
    background-color: white;
    margin: 0 auto;
    margin-top: 80px; 
    border-radius: 6px;/*圆角*/ 
}

.form_title{
    height: 80px;    
    line-height: 80px ;  /* line-height = height   */
    text-align: center;
    color: rgba(113,115,118,1);;
    font-family: PingFangSC-Regular,PingFang SC; /*字体*/
    font-size: 18px;
}

.myform{
    width: 80%;
    height: 280px;
   
    margin: 0 auto;
    margin-top: 40px; 
}
.myform .user_name,.user_pwd{
    width: 320px;
    height: 40px;
    display: block;
    margin:  0 auto;
    margin-bottom: 20px;
    border-radius: 4px;
    outline: none;  
    border:none;
    background-color: #f6f7f9;
    padding-left: 10px;
    padding-right: 10px;
}


.myform .loginBtn{
    width: 320px;
    height: 42px;
    background-color: rgba(230, 69, 102, 0.1);
    color: rgb(146, 145, 145);
    display: block;
    margin:  0 auto;
    margin-top: 10px;
    border: none;
    border-radius: 4px;
}

.myform .loginBtn:hover{
    background-color: rgba(230, 69, 101, 0.196);
}

.login_tip{
    display: block;
    width: 340px;
    height: 30px;
    font-size: 10px;
    color: red;
    text-align: center;
}
 


js_02_登录验证.js


// document : HTML 网页文档
// query 查询, Selector 选择器
var loginTip = document.querySelector(".login_tip");
var usernameEle = document.querySelector(".user_name");
//onblur : 光标移开输入框
usernameEle.onblur = checkUsername;
// 验证用户名
function checkUsername(){
    var username = usernameEle.value;
    console.log("用户名是:" + username)
   
    if(username == '' || username.length ==0){
        loginTip.innerText = '用户名不能为空';
        return false;
    }else{
        loginTip.innerText = '';
        return true;
    }
  
}

// 光标移开密码域,验证密码是否为空
var userPwdEle = document.querySelector('.user_pwd');
userPwdEle.onblur = checkUserPwd;
// 验证密码
function checkUserPwd(){
    var userPwd = userPwdEle.value;
    if(userPwd =='' || userPwd.length == 0){
        loginTip.innerText = '密码不能为空';
        return false;
    }else{
        loginTip.innerText = '';
        return true;
    }
}

// 登录表单提交验证
document.querySelector(".myform").onsubmit = function(){
      var result  =  checkUsername() && checkUserPwd();
      console.log(result);
      return result;
}



index.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>首页</title>
    <link href="css/css_04_首页.css" rel="stylesheet"/>
    <link rel="shortcut icon" href="images/favicon.ico" />
</head>
<body>
<!-- ======================1. 头部 ======================-->
<div class="header">
    <div class="logo">
        <a href=""> </a>
    </div>

    <div class="nav">
        <ul class="head-nav">
            <li><a href="" class="first-item">首页</a></li>
            <li><a href="">菜品</a></li>
            <li><a href="">店铺</a></li>
            <li><a href="">热卖</a></li>
            <li><a href="">优惠券</a></li>

        </ul>
    </div>

    <div class="search">
        <form>
            <input type="text" class="search-kw" >
            <input type="submit" class="search-btn" value="搜索"/>
        </form>
    </div>
    <div class="login">
        <a href="login.html">登录</a>
        <a href="">注册</a>
    </div>
</div>

<!-- ======================2. 横幅 banner ======================-->
<div class="banner">
    <img src="images/bg1.jpg" />
</div>


<!-- =======================3. 热门商品================== -->
<h3 class="pro-title"> 热门商品</h3>
<div class="pro-list">
    <ul>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro2.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro3.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro2.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro3.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro2.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro3.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro2.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>
        <li>
            <a href="css_06_商品详情.html">
                <img class="pro-img" src="images/pro3.webp" />
            </a>

            <a href="" class="pro-name-a">
                <p  class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
            </a>

            <div class="pro-price">
                <i></i>
                <span>6999.00</span>
            </div>
        </li>


    </ul>
</div>


</body>
</html>



login.html


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="css/css_11_login.css" />
  <script src="js/jquery-3.7.0.min.js"></script>

</head>
<body>
<div class="login_form">
  <h4 class="form_title">登录</h4>

  <form class="myform" method="post" >
    <span class="login_tip"></span>
    <input type="text"  class="user_name" placeholder="您的邮箱或手机号" name="customerName"/>
    <input type="password"  class="user_pwd"  placeholder="您的密码" name="customerPwd"/>
    <input type="button" value="登录" class="loginBtn">
  </form>
</div>


<script src="js/js_02_登录验证.js"></script>



<script>
  $(".loginBtn").click(function (){
    var url = "http://localhost:80/app/customer/login";
    var formData = $(".myform").serialize();
    $.post(url,formData,function (result){
      console.log(result)
      if(result.code ==200){
        localStorage.setItem("token",result.data);  // 1.保存token
        window.location.href = "index.html";
      }else{
        $(".login_tip").text(result.data);
      }
    })
  })
</script>
</body>
</html>



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.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_login</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>springboot_login</name>
    <description>springboot_login</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.0</version>
        </dependency>











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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>




        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generate -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>
    </dependencies>

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

</project>




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/574029.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Chisel 入门(2)运算符

Chisel 入门(2) 运算符 逻辑运算符 ChiselExplanationwidth!x逻辑非1x && y逻辑与1x||y逻辑或1 位操作运算符 ChiselExplanationwidthin Verilog~x位反w(x)~ signal_xx & y位与max(w(x), w(y))signal_x & signal_yx | y位或max(w(x), w(y))signal_x | sign…

Oracle数据库的AI能力分析,释放企业数据价值

解锁Oracle数据库的AI潜力 Oracle数据库提供了一系列的AI能力&#xff0c;旨在帮助企业和开发者更高效地利用人工智能技术。以下是Oracle数据库AI能力的一些关键点&#xff1a;1. AI向量相似性搜索&#xff1a;Oracle Database 23c引入了AI Vector Search功能&#xff0c;该功…

基于B2C的网上拍卖系统——秒杀与竞价

点击下载源码和论文https://download.csdn.net/download/liuhaikang/89222887 课题背景及意义 随着网络的进一步普及和电子商务的高速发展&#xff0c;越来越多的人们开始在网络中寻求方便。网上网物具备了省时、省事、省心、高效等特点&#xff0c;从而受到越来越多人的欢迎。…

SpringCloud系列(16)--将服务提供者Provider注册进Zookeeper

前言&#xff1a;在上一章节中我们说明了一些关于Eureka自我保护模式&#xff0c;而且自上一章节起关于Eureka的知识已经讲的差不多了&#xff0c;不过因为Eureka已经停更了&#xff0c;为了安全考虑&#xff0c;我们要用还在更新维护的注册中心来取代Eureka&#xff0c;而本章…

C语言:复习

文章目录 思维导图数组和指针库函数的模拟实现判断大小端 最近知识学的差不多了&#xff0c;因此开始复习&#xff0c;本篇开始的是对于C语言的复习 思维导图 下面就依据下图&#xff0c;进行内容的整理 数组和指针 这个模块算是C语言中比较大的一个模块了&#xff0c;具体概…

Three.js——基础材质、深度材质、法向材质、面材质、朗伯材质、Phong材质、着色器材质、直线和虚线、联合材质

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

如何使用rdtsc和C/C++来测量运行时间(如何使用内联汇编和获取CPU的TSC时钟频率)

本文主要是一个实验和思维扩展&#xff0c;是一个初步的尝试&#xff0c;旨在研究一些时间测量实现和在 C/C 中内联汇编和汇编函数的使用方法。除非你有特殊用途&#xff0c;不然不要使用汇编指令来实现这个功能。在“扩展阅读”部分会列出了一些不需要内联汇编实现的方法。 写…

猫头虎分享已解决Bug || TypeError: Cannot read property ‘map‘ of undefined**

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

4.25 C高级

思维导图 作业 2.输入两个数&#xff0c;实现两个数的排序 3.输入一个数&#xff0c;计算是否是水仙花 if ((g*g*gs*s*sb*b*bnum)) then echo YES else echo no fi 4.输入一个成绩实现登记判断 90-100A 80-89B 70-79C 60-69D 0-59E

“追忆似水年华 展望美好未来”——生命故事小组忆童趣活动

在人生的长河中&#xff0c;童年是明亮色彩的日子&#xff0c;但随着岁月的流逝&#xff0c;这些回忆有时会变得模糊&#xff0c;为唤起他们对美好童年的回忆&#xff0c;2024年4月9日上午9点&#xff0c;由成都市社会组织社区和社工人才服务中心支持&#xff0c;新都区民政局指…

OpenHarmony语言基础类库【@ohos.util.HashMap (非线性容器HashMap)】

HashMap底层使用数组链表红黑树的方式实现&#xff0c;查询、插入和删除的效率都很高。HashMap存储内容基于key-value的键值对映射&#xff0c;不能有重复的key&#xff0c;且一个key只能对应一个value。 HashMap和[TreeMap]相比&#xff0c;HashMap依据键的hashCode存取数据&…

文旅元宇宙解决方案|人工智能、虚拟数字人、导览系统深度应用

随着数字技术的飞速发展&#xff0c;文旅行业正迎来一场前所未有的变革。道可云文旅元宇宙平台以其前瞻性的技术视野和创新的解决方案&#xff0c;为各级文旅主管部门、旅游景区、博物馆、艺术展览馆等单位提供了全新的智慧景区导览、元宇宙场景搭建、AR场景开发以及数字人导游…

市场上免费且高效的云渲染平台,渲染100邀请码7788

在当今数字化时代&#xff0c;云渲染服务因其便捷性和高效性而日益受到追捧&#xff0c;广泛应用于建筑设计、影视制作和视觉艺术等多个领域。它不仅能够显著缩短项目完成的时间&#xff0c;还能大幅提升工作效率。 接下来&#xff0c;我们将探讨一些市场上公认的优质且免费的…

【Qt常用控件】—— QWidget 核心属性

目录 &#xff08;一&#xff09;控件概述 1.1 关于控件体系的发展 &#xff08;二&#xff09;QWidget 核心属性 2.1 核心属性概览 2.2 enabled 2.3 geometry 2.4 windowTitle 2.5 windowIcon 2.6 windowOpacity 2.7 cursor 2.8 font 2.9 toolTip 2.10 focus…

数据结构四:线性表之带头结点的单向循环循环链表的设计

前面两篇介绍了线性表的顺序和链式存储结构&#xff0c;其中链式存储结构为单向链表&#xff08;即一个方向的有限长度、不循环的链表&#xff09;&#xff0c;对于单链表&#xff0c;由于每个节点只存储了向后的结点的地址&#xff0c;到了尾巴结点就停止了向后链的操作。也就…

MySQL统计一个表的行数,使用count(1), count(字段), 还是count(*)?

为什么要使用count函数&#xff1f; 在开发系统的时候&#xff0c;我们经常要计算一个表的行数。比如我最近开发的牛客社区系统&#xff0c;有一个帖子表&#xff0c;其中一个功能就是要统计帖子的数量&#xff0c;便于分页显示计算总页数。 CREATE TABLE discuss_post (id i…

展览模型一般怎么打灯vray---模大狮模型网

在展览模型的设计中&#xff0c;灯光的运用是至关重要的&#xff0c;它不仅能够增强展品的视觉效果&#xff0c;还可以营造出独特的氛围和情感。在利用V-Ray进行灯光设置时&#xff0c;有一些常用的技巧和方法可以帮助设计师实现理想的展览效果。在本文中&#xff0c;我们将介绍…

漏洞修复优先级考虑-不错的思路

权威说法&#xff1a; 漏洞利用预测评分系统 &#xff08;EPSS&#xff09; 是一项数据驱动的工作&#xff0c;用于估计软件漏洞在野外被利用的可能性&#xff08;概率&#xff09; https://www.first.org/epss/ GitHub - TURROKS/CVE_Prioritizer: Streamline vulnerability…

在windows上安装MySQL数据库全过程

1.首先在MySQL的官网找到其安装包 在下图中点击MySQL Community(gpl) 找到MySQL Community Server 选择版本进行安装包的下载 2.安装包&#xff08;Windows (x86, 64-bit), MSI Installer&#xff09;安装步骤 继续点击下一步 继续进行下一步&#xff0c;直到出现此界面&#…

基于小程序实现的惠农小店系统设计与开发

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…
最新文章