书城项目第八阶段:使用Filter过滤器实现后台的权限管理

简介: 书城项目第八阶段:使用Filter过滤器实现后台的权限管理

7、书城第八阶段

1、使用Filter过滤器拦截/pages/manager/所有内容,实现权限检查

新建com.atguigu/filter/MangerFilter

package com.atguigu.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class ManageFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest= (HttpServletRequest) servletRequest;
        Object user = httpServletRequest.getSession().getAttribute("user");
        if (user==null){
            httpServletRequest.getRequestDispatcher("/pages/user/login.jsp").forward(servletRequest,servletResponse);
        }else {
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }
    @Override
    public void destroy() {
    }
}

配置web.xml

<filter>
        <filter-name>ManageFilter</filter-name>
        <filter-class>com.atguigu.filter.ManageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ManageFilter</filter-name>
        <url-pattern>/pages/manager/*</url-pattern>
        <url-pattern>/manager/bookServlet</url-pattern>
    </filter-mapping>

2、ThreadLocal的使用

ThreadLocal的作用,它可以解决多线程的数据安全问题。
ThreadLocal它可以给当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合)

Threadlocal的特点:

1、Threadlocal可以为当前线程关联一个数据。(它可以像Map一样存取数据,key为当前线程)

2、每一个Threadlocal对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 Threadlocal对象实例。

3、每个Threadlocal对象实例定义的时候,一般都是static类型

4、Threadlocal中保存数据,在线程销毁后。会由JVM虚拟自动释放。

新建tmp/src/threadlocal/ThreadLocalTest

package threadlocal;
import java.util.Random;
public class ThreadLocalTest {
//    public final static Map<String,Object> data=new ConcurrentHashMap<>();线程安全
//    public final static Map<String,Object> data=new Hashtable<>();
    public static ThreadLocal<Object> threadLocal=new ThreadLocal<>();
    private static Random random=new Random();
    public static class Task implements Runnable{
        @Override
        public void run() {
//            threadLocal.set("abc");
//            threadLocal.set("bbj");
//            System.out.println(threadLocal.get());//bbj 覆盖
            //在run方法中 ,随机生成一个变量(线程要关联的数据),然后一当前线程名为key保存到map中
            Integer i = random.nextInt(1000);
            //获取当前线程名
            String name = Thread.currentThread().getName();
            System.out.println("线程["+name+"]生成的随机数是:"+i);
//            data.put(name,i);
            threadLocal.set(i);
            //模拟操作
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            new OrderService().createOrder();
            //在Run方法结束之前,以当前线程名获取出数据并打印。查看是否可以取出操作
//            Object o = data.get(name);
            Object o=threadLocal.get();
            System.out.println("线程["+name+"]快结束时取出关联的数据是:"+o);
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Task()).start();
        }
    }
}

新建threadlocal/OrderService

package threadlocal;
public class OrderService {
    public void createOrder(){
        String name = Thread.currentThread().getName();
        System.out.println("OrderService 当前线程["+name+"]中保存的数据是:"+ThreadLocalTest.threadLocal.get());
        new OrderDao().saveOrder();
    }
}

新建threadlocal/OrderDao

package threadlocal;
public class OrderDao {
    public void saveOrder(){
        String name = Thread.currentThread().getName();
//        System.out.println("OrderDao 当前线程["+name+"]中保存的数据是:"+ThreadLocalTest.data.get(name));
        System.out.println("OrderDao 当前线程["+name+"]中保存的数据是:"+ThreadLocalTest.threadLocal.get());
    }
}

结果


3、使用Filter和ThreadLocal组合管理事务

3.1 使用ThreadLocal确保所有操作都使用同一个Connection来实现

验证是否为同一线程

修改 OrderServiceImpl 模拟错误

package com.atguigu.service.impl;
import com.atguigu.dao.BookDao;
import com.atguigu.dao.OrderDao;
import com.atguigu.dao.OrderItemDao;
import com.atguigu.dao.impl.BookDaoImpl;
import com.atguigu.dao.impl.OrderDaoImpl;
import com.atguigu.dao.impl.OrderItemDaoImpl;
import com.atguigu.pojo.*;
import com.atguigu.service.OrderService;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class OrderServiceImpl implements OrderService {
    private OrderDao orderDao =new OrderDaoImpl();
    private OrderItemDao orderItemDao=new OrderItemDaoImpl();
    private BookDao bookDao=new BookDaoImpl();
    @Override
    public String createOrder(Cart cart, Integer userId) {
        System.out.println("OrderServiceImpl 程序在["+Thread.currentThread().getName()+"]中");
        //订单号==唯一性
        String orderId=System.currentTimeMillis()+""+userId;
        //创建一个订单对象
        Order order=new Order(orderId,new Date(),cart.getTotalPrice(),0,userId);
        //保存订单
        orderDao.saveOrder(order);
        //模拟错误
        int i=12/0;
        //遍历购物车中每一个商品项转换为订单保存到数据库
        for (Map.Entry<Integer, CartItem>entry:cart.getItems().entrySet()) {
            //获取购物车每一个商品项
            CartItem cartItem=entry.getValue();
            //转换为订单
            OrderItem orderItem=new OrderItem(null,cartItem.getName(),cartItem.getCount(),cartItem.getPrice(),cartItem.getTotalPrice(),orderId);
            //保存到数据库
            orderItemDao.saveOrderItem(orderItem);
            //更新库存和销量
            Book book = bookDao.queryBookById(cartItem.getId());
            book.setSales(book.getSales()+cartItem.getCount());
            book.setStock(book.getStock()-cartItem.getCount());
            bookDao.updateBook(book);
        }
        //清空购物车
        cart.clear();
        return orderId;
    }
    @Override
    public List<Order> showAllOrders() {
        return orderDao.queryOrders();
    }
    @Override
    public int sendOrder(String orderId) {
        return orderDao.changeOrderStatus(orderId,1);
    }
    @Override
    public List<OrderItem> showOrderDetail(String orderId) {
        return orderItemDao.queryOrderItemByOrderId(orderId);
    }
    @Override
    public List<Order> showMyOrders(int userId) {
        return orderDao.queryByUserId(userId);
    }
    @Override
    public int receiverOrder(String orderId) {
        return orderDao.changeOrderStatus(orderId,2);
    }
}

结果 网页,添加购物车去结账

t_order表无记录

t_order_item有记录

原理

修改 JdbcUtils

package com.atguigu.utils;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
    private static DruidDataSource dataSource;
    private static ThreadLocal<Connection> conns=new ThreadLocal<>();
    static {
        try {
            Properties properties=new Properties();
            //读取jdbc.properties属性配置文件
            InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            //从流中加载数据
            properties.load(inputStream);
            //创建数据连接池
            dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);//Ctrl+ALT+T
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 获取数据库连接池中的连接
     * @return 如果返回null,说明获取连接失败<br/> 有值就是获取连接成功
     */
    public static Connection getConnection(){
        Connection conn=conns.get();
        if (conn==null){
            try {
                conn= dataSource.getConnection();//从数据库连接池中获取连接
                conns.set(conn);//保存到ThreadLocal对象中,供后面的jdbc操作使用
                conn.setAutoCommit(false);//设置为手动管理事务
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        return conn;
    }
    /**
     * 提交事务,并关闭释放连接
     */
    public static void commitAndClose(){
        Connection connection=conns.get();
        if (connection!=null){//如果不等于null,说明之前使用过连接,操作过数据库
            try {
                connection.commit();//提交 事务
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }finally {
                try {
                    connection.close();//关闭连接,释放资源
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        //一定要执行remove操作,否则就会出错。(因为Tomcat服务器底层使用了线程池技术)
        conns.remove();
    }
    /**
     * 回滚事务,并关闭释放连接
     */
    public static void rollbackAndClose(){
        Connection connection=conns.get();
        if (connection!=null){//如果不等于null,说明之前使用过连接,操作过数据库
            try {
                connection.rollback();//回滚 事务
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }finally {
                try {
                    connection.close();//关闭连接,释放资源
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        //一定要执行remove操作,否则就会出错。(因为Tomcat服务器底层使用了线程池技术)
        conns.remove();
    }
        /**
         * 关闭连接,放回数据库连接池
         * @param conn
        public static void close(Connection conn){
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
         */
}

修改 JdbcUtilsTest

package com.atguigu.test;
import org.junit.Test;
public class JdbcUtilsTest {
    @Test
    public void testJdbcUtils(){
//        for (int i = 0; i < 100; i++) {
//            Connection connection = JdbcUtils.getConnection();
//            System.out.println(connection);
//            JdbcUtils.close(connection);
//        }
    }
}

修改 BaseDao

package com.atguigu.dao;
import com.atguigu.utils.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
public abstract class BaseDao {
    //使用DbUtils操作数据库
    private QueryRunner queryRunner=new QueryRunner();
    /**
     * update() 方法用来执行,Insert\Update\Delete语句
     * @return 如果返回-1,说明执行失败<br/>返回其他表示影响的行数
     */
    public int update(String sql,Object... args){
        System.out.println("BaseDao 程序在["+Thread.currentThread().getName()+"]中");
        Connection connection= JdbcUtils.getConnection();
        try {
            return queryRunner.update(connection,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    /**
     * 查询返回一个javabean的sql语句
     * @param type 返回的对象类型
     * @param sql 执行的sql语句
     * @param args sql对应的参数值
     * @param <T> 返回类型的泛型
     * @return
     */
    public <T> T queryForOne(Class<T> type,String sql,Object... args){
        Connection con=JdbcUtils.getConnection();
        try {
            return queryRunner.query(con,sql,new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    /**
     * 查询返回多个javabean的sql语句
     * @param type 返回的对象类型
     * @param sql 执行的sql语句
     * @param args sql对应的参数值
     * @param <T> 返回类型的泛型
     * @return
     */
    public <T>List<T> queryForList(Class<T> type,String sql,Object... args){
        Connection con=JdbcUtils.getConnection();
        try {
            return queryRunner.query(con,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    /**
     * 执行返回一行一列的sql语句
     * @param sql 执行的sql语句
     * @param args sql对应的参数值
     * @return
     */
    public Object queryForSingleValue(String sql,Object... args){
        Connection conn=JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn,sql,new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

修改 OrderServlet

package com.atguigu.web;
import com.atguigu.pojo.Cart;
import com.atguigu.pojo.User;
import com.atguigu.service.OrderService;
import com.atguigu.service.impl.OrderServiceImpl;
import com.atguigu.utils.JdbcUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class OrderServlet extends BaseServlet {
    private OrderService orderService = new OrderServiceImpl();
    /**
     * 生成订单
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void createOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //先获取Cart购物车对象
        Cart cart = (Cart) req.getSession().getAttribute("cart");  //获取Userid
        User loginUser = (User) req.getSession().getAttribute("user");
        if (loginUser == null) {
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp);
            return;
        }
        System.out.println("OrderServlet 程序在["+Thread.currentThread().getName()+"]中");
        Integer userId = loginUser.getId();
        //调用orderservice.createorder(cart,userid);生成订单
        String orderId = null;
        try {
            orderId = orderService.createOrder(cart, userId);
            JdbcUtils.commitAndClose();//提交事务
        } catch (Exception e) {
            JdbcUtils.rollbackAndClose();//回滚事务
            e.printStackTrace();
        }
//        req.setAttribute("orderId",orderId);
        //请求转发至pages/cart/checkout.jsp
//        req.getRequestDispatcher("/pages/cart/checkout.jsp").forward(req,resp);
        req.getSession().setAttribute("orderId", orderId);
        resp.sendRedirect(req.getContextPath() + "/pages/cart/checkout.jsp");
    }
    /**
     * 查看所有订单
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void showAllOrders(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 发货
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void sendOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 查看订单详情
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void showOrderDetail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 查看我的订单
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void showMyOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 签收订单/确认收货
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void receiverOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

结果 网页,添加购物车去结账


3.2、使用Filter统一给所有Service方法都加上try-catch来实现管理事务


新建 filter/TransactionFilter

package com.atguigu.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public abstract class BaseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action=req.getParameter("action");
//        System.out.println(action);
        //action的value和调用的方法名是统一的
//        if ("login".equals(action)){
            System.out.println("处理登录的需求");
//           login(req,resp);
//        }else if ("regist".equals(action)){
            System.out.println("处理注册的需求");
//            regist(req,resp);
//        }
        //反射
        try {
            //获取action业务鉴别字符串,获取相应的业务方法 反射对象
            Method method = this.getClass().getDeclaredMethod(action,HttpServletRequest.class,HttpServletResponse.class);
            //调用目标业务方法
            method.invoke(this,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);//把异常抛给Filter过滤器
        }
    }
}

配置web.xml

<filter>
        <filter-name>TransactionFilter</filter-name>
        <filter-class>com.atguigu.filter.TransactionFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>TransactionFilter</filter-name>
        <!--  /*当前工程下所有请求      -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

修改 OrderServlet

package com.atguigu.web;
import com.atguigu.pojo.Cart;
import com.atguigu.pojo.User;
import com.atguigu.service.OrderService;
import com.atguigu.service.impl.OrderServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class OrderServlet extends BaseServlet {
    private OrderService orderService = new OrderServiceImpl();
    /**
     * 生成订单
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void createOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //先获取Cart购物车对象
        Cart cart = (Cart) req.getSession().getAttribute("cart");  //获取Userid
        User loginUser = (User) req.getSession().getAttribute("user");
        if (loginUser == null) {
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp);
            return;
        }
        System.out.println("OrderServlet 程序在["+Thread.currentThread().getName()+"]中");
        Integer userId = loginUser.getId();
        //调用orderservice.createorder(cart,userid);生成订单
        String orderId = orderService.createOrder(cart, userId);
//        req.setAttribute("orderId",orderId);
        //请求转发至pages/cart/checkout.jsp
//        req.getRequestDispatcher("/pages/cart/checkout.jsp").forward(req,resp);
        req.getSession().setAttribute("orderId", orderId);
        resp.sendRedirect(req.getContextPath() + "/pages/cart/checkout.jsp");
    }
    /**
     * 查看所有订单
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void showAllOrders(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 发货
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void sendOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 查看订单详情
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void showOrderDetail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 查看我的订单
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void showMyOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    /**
     * 签收订单/确认收货
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void receiverOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

修改 BaseServlet

package com.atguigu.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public abstract class BaseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action=req.getParameter("action");
//        System.out.println(action);
        //action的value和调用的方法名是统一的
//        if ("login".equals(action)){
            System.out.println("处理登录的需求");
//           login(req,resp);
//        }else if ("regist".equals(action)){
            System.out.println("处理注册的需求");
//            regist(req,resp);
//        }
        //反射
        try {
            //获取action业务鉴别字符串,获取相应的业务方法 反射对象
            Method method = this.getClass().getDeclaredMethod(action,HttpServletRequest.class,HttpServletResponse.class);
            //调用目标业务方法
            method.invoke(this,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);//把异常抛给Filter过滤器
        }
    }
}

3.3、将所有异常都交给Tomcat,让Tomcat显示友好的错误信息页面

在web.xml 中我们可以通过错误页面配置来进行管理。

新建 pages/error/error500.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>error500</title>
    <%--静态包含 base标签,css样式,jquery文件 --%>
    <%@ include file="/pages/common/head.jsp"%>
</head>
<body>
很抱歉,您访问的页面不存在,或已经被删除!!!<br>
<a href="index.jsp">返回首页</a>
</body>
</html>

并配置 web.xml

 <!-- error-page标签配置,服务器出错之后,自动跳转的页面   -->
    <error-page>
        <!--  error-code是错误类型      -->
        <error-code>500</error-code>
        <!-- location标签表示,要跳转的页面路径-->
        <location>/pages/error/error500.jsp</location>
    </error-page>

修改 TransactionFilter

package com.atguigu.filter;
import com.atguigu.utils.JdbcUtils;
import javax.servlet.*;
import java.io.IOException;
public class TransactionFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        try {
            filterChain.doFilter(servletRequest,servletResponse);
            JdbcUtils.commitAndClose();//提交事务
        } catch (Exception e) {
            JdbcUtils.rollbackAndClose();//回滚事务
            e.printStackTrace();
            throw new RuntimeException(e);//把异常抛给Tomcat管理展示友好的错误页面
        }
    }
    @Override
    public void destroy() {
    }
}

新建error/error404.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>error404</title>
    <%--静态包含 base标签,css样式,jquery文件 --%>
    <%@ include file="/pages/common/head.jsp"%>
</head>
<body>
很抱歉,您访问的页面不存在,或已经被删除!!!<br>
<a href="index.jsp">返回首页</a>
</body>
</html>

配置web.xml

<!-- error-page标签配置,服务器出错之后,自动跳转的页面   -->
    <error-page>
        <!--  error-code是错误类型      -->
        <error-code>404</error-code>
        <!-- location标签表示,要跳转的页面路径-->
        <location>/pages/error/error404.jsp</location>
    </error-page>
相关文章
|
7月前
|
SQL XML Java
若依框架 --- 使用数据权限功能
若依框架 --- 使用数据权限功能
878 0
|
6月前
|
Java 数据安全/隐私保护 Spring
SpringSecurity6从入门到实战之默认用户的生成流程
该文档介绍了SpringSecurity6中默认用户的生成流程。在`SecurityAutoConfiguration`源码中,通过`SecurityProperties`配置类,系统默认创建了一个名为&quot;user&quot;的用户,其密码是一个随机生成的UUID。这个用户是在没有在`application.properties`中设置相关配置时自动创建的。
|
7月前
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(三)
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(三)
332 1
|
7月前
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(一)
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(一)
342 1
|
7月前
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(二)
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(二)
178 0
|
5月前
|
存储 前端开发 JavaScript
前端菜单及按钮权限拦截,实现方案及思路
此实现方案基于vue框架,并需要依赖vue项目相关的库,router、store等等;前端同学要与后端同学协商,常规是让后端返回一个树结构的菜单数据,并且将所有的涉及权限控制的页面path给到后端,如果是按钮,需要把所有的按钮 code 码统一下,这是前期工作,很重要。
|
自然语言处理 安全
Web3.0钱包系统开发(开发功能)/指南教程/步骤流程/方案设计/项目逻辑/规则玩法/案例源码
Wallet type selection: Determine the type of wallet, which can be a browser plugin wallet, mobile application wallet, or online web wallet. The choice of wallet type should be based on the target user group and usage environment.
|
7月前
|
缓存 前端开发 JavaScript
若依框架中的权限控制逻辑 ---- 菜单
若依框架中的权限控制逻辑 ---- 菜单
688 0
|
缓存 小程序 前端开发
【易售小程序项目】请求包创建+登录功能实现【基于若依管理系统开发】
【易售小程序项目】请求包创建+登录功能实现【基于若依管理系统开发】
144 0
|
Java
JavaWeb用户信息管理系统-创建登录业务的Filter
JavaWeb用户信息管理系统-创建登录业务的Filter
41 0