用户模块

要登陆后才能购买,因此我们先写购买模块.

设计实体

    private String id;
private String username;
private String password;
private String email;
private String cellphone;
private String address;

//各种setter、getter

设计数据库表

CREATE TABLE user (

id VARCHAR(40) PRIMARY KEY,
username VARCHAR(20) NOT NULL,
cellphone VARCHAR(20) NOT NULL,
address VARCHAR(40) NOT NULL,
email VARCHAR(30),
password VARCHAR(30) NOT NULL

);

编写DAO

/**
* 用户的登录注册模块
* 1:登陆
* 2:注册
* 3:根据id查找具体的用户
*/
public class UserDaoImpl {



public void register(User user) {

QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

String sql = "INSERT INTO user (id,username,cellphone,address,email,password) VALUES(?,?,?,?,?,?)";
try {

queryRunner.update(sql, new Object[]{user.getId(),user.getUsername(), user.getCellphone(), user.getAddress(), user.getEmail(), user.getPassword()});
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

public User login(String username, String password) {

QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

String sql = "SELECT * FROM user WHERE username = ? AND password=?";
try {

return (User) queryRunner.query(sql, new Object[]{username, password}, new BeanHandler(User.class));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

public User find(String id) {

QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

String sql = "SELECT * FROM user WHERE id=?";
try {

return (User) queryRunner.query(sql, id, new BeanHandler(User.class));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

}

测试DAO

public class UserDemo {
UserDaoImpl userDao = new UserDaoImpl();

@Test
public void add() {

User user = new User();
user.setId("1");
user.setUsername("zhong");
user.setPassword("123");
user.setCellphone("10085");
user.setAddress("广州萝岗");
user.setEmail("40368324234234@QQ.com");

userDao.register(user);
}

@Test
public void find() {

String id = "1";
User user = userDao.find(id);

System.out.println(user.getEmail());
}

@Test
public void login() {
String username = "zhong";
String password = "123";
User user = userDao.login(username, password);

System.out.println(user.getAddress());
}
}

抽取DAO

public interface UserDao {
void register(User user);

User login(String username, String password);

User find(String id);
}

编写Service

    private UserDao userDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.UserDaoImpl", UserDao.class);

public void registerUser(User user) {
userDao.register(user);
}

public User loginUser(String username,String password) {
return userDao.login(username, password);
}

public User findUser(String id) {
return userDao.find(id);
}

前台样式

  • head.jsp

     用户名:      密码:       登陆     注册
  • head.css

#body {
position: relative;
}
#user {
position: absolute;
margin-top: 130px;
margin-left: 1364px;
}
  • 效果:

image.png


实现登陆注册功能

当点击登陆按钮的时候,把数据带过去给Servlet,让Servlet调用BusinessService方法,实现登陆。注册同理.....因此,我们需要用到JavaScript代码

  • head.jsp

       用户名:      密码:        登陆      注册               欢迎您:${user.username} 注销
  • javaScript代码

    <script type="text/javascript">

function login() {
//得到输入框的数据
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;

//跳转到相对应的Servlet上
window.location.href = "${pageContext.request.contextPath}/UserServlet?method=login&username=" + username + "&password=" + password;
}

function register() {

//跳转到注册页面
window.location.href = "${pageContext.request.contextPath}/client/register.jsp";
}
</script>
  • UserServlet

        String method = request.getParameter("method");

BussinessServiceImpl service = new BussinessServiceImpl();
if (method.equals("login")) {

try {
//得到页面传递过来的数据
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = service.loginUser(username, password);

request.getSession().setAttribute("user",user);
request.getRequestDispatcher("/client/head.jsp").forward(request, response);

} catch (Exception e) {
request.setAttribute("message", "登陆失败了!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}

} else if (method.equals("register")) {

try {
//得到JSP传递过来的数据,封装成Bean对象
User user = WebUtils.request2Bean(request, User.class);
user.setId(WebUtils.makeId());

service.registerUser(user);

request.setAttribute("message", "注册成功了!");

} catch (Exception e) {
e.printStackTrace();
request.setAttribute("message", "注册失败了!");
}
request.getRequestDispatcher("/message.jsp").forward(request, response);
} else if (method.equals("Logout")) {

//销毁session
request.getSession().invalidate();

//回到首页
request.getRequestDispatcher("/client/head.jsp").forward(request, response);

}

购买模块

在显示图书的时候,顺便添加购买的超链接

     购买

设计购物车实体

如果不清楚为什么这样设计,可参考我之前的博文:http://blog.csdn.net/hon_3y/article/details/56481439#t5

  • Cart实体

public class Cart {

private Map<String, CartItem> map = new HashMap<>();
private double price;


//提供把商品添加到购物的功能
public void addBook2Cart(Book book) {

//得到对应的购物项
CartItem cartItem = map.get(book.getId());

//如果是null,说明购物车还没有该购物项
if (cartItem == null) {
cartItem = new CartItem();
cartItem.setQuantity(1);
cartItem.setBook(book);
cartItem.setPrice(book.getPrice());

//把购物项加到购物车中
map.put(book.getId(), cartItem);
} else {

//如果购物车有该购物项了,那么将购物项的数量+1
cartItem.setQuantity(cartItem.getQuantity() + 1);
}
}


//购物车的价钱是购物项价钱的总和
public double getPrice() {

double totalPrice = 0;
for (Map.Entry<String, CartItem> me : map.entrySet()) {
CartItem cartItem = me.getValue();
totalPrice += cartItem.getPrice();
}

return totalPrice;
}

public Map<String, CartItem> getMap() {
return map;
}

public void setMap(Map<String, CartItem> map) {
this.map = map;
}


public void setPrice(double price) {
this.price = price;
}
}

设计购物项实体

public class CartItem {

private Book book;
private double price;
private int quantity;

public double getPrice() {
return this.book.getPrice() * this.quantity;
}

public void setPrice(double price) {
this.price = price;
}

public Book getBook() {
return book;
}

public void setBook(Book book) {
this.book = book;
}
public int getQuantity() {
return quantity;
}

public void setQuantity(int quantity) {
this.quantity = quantity;
}
}

处理用户想要买的书籍Servlet

     购买
  • BuyServlet

        BussinessServiceImpl service = new BussinessServiceImpl();

//先检查该用户是否登陆了。
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
request.setAttribute("message", "您还没登陆,请登陆了再来购买");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return ;
}

//如果登陆了...

//得到该用户的购物车
Cart cart = (Cart) request.getSession().getAttribute("cart");
if (cart == null) {
cart = new Cart();
request.getSession().setAttribute("cart", cart);
}

//得到用户想买的书籍
String book_id = request.getParameter("book_id");
Book book = service.findBook(book_id);

//把书籍添加到购物车中
service.buyBook(cart, book);
request.setAttribute("message", "该商品已添加到购物车中");
request.getRequestDispatcher("/message.jsp").forward(request,response);

提供显示购物车商品的Servlet

        //先判断该用户是否登陆了
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
request.setAttribute("message", "您还没有登陆呢!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}

//如果登陆了.....
Cart cart = (Cart) request.getSession().getAttribute("cart");

//把该用户的购物车给JSP页面显示
request.setAttribute("cart", cart);
request.getRequestDispatcher("/client/listCart.jsp").forward(request, response);

显示购物车的JSP页面

     您还没有购买过任何商品哦!!!              您购物车下有如下的商品:                    书名:            作者:            数量:            价钱:                                              ${cartItme.value.book.name}                ${cartItme.value.book.author}                ${cartItme.value.quantity}                ${cartItme.value.price}

效果:

image.png


订单模块

在前台用户界面中,当用户要把购物车付款时,应该提供生成订单的超链接....

image.png


设计订单实体

订单应该包含id,收货人信息,下单的时间,订单的总价,订单的状态【有无发货】..而不应该包含商品的信息的。商品的信息用一个专门的”订单项“来表示

一个订单对应多个订单项,这是一对多的关系!

    private String id;

//下单的时间、日期、状态
private Date date;
private double price;
private boolean state;

//一个用户可以有多个订单,把用户记住
private String user_id;

//一个订单中有多个订单项
private Set<OrderItem> items = new HashSet<>();

//各种的setter和getter

设计订单项实体

    private String id;


//一本书对应多个订单项,订单项一定是由书组成,记住书
private String book_id;

private double price;
private int quantity;

//各种的setter和getter

设计数据库表

  • 订单表

mysql不能创建名为”order”的表,后边加个s就可以

CREATE TABLE orders (
id VARCHAR(40) PRIMARY KEY,
date DATE NOT NULL,
user_id VARCHAR(40) NOT NULL,
state BOOLEAN,
price DOUBLE,
CONSTRAINT user_id_FK FOREIGN KEY (user_id) REFERENCES user (id)
);
  • 订单项表:

CREATE TABLE orderItem (
id VARCHAR(40) PRIMARY KEY,
price DOUBLE,
quantity INT,
order_id VARCHAR(40) ,
book_id VARCHAR(40) ,
CONSTRAINT order_id_FK FOREIGN KEY (order_id) REFERENCES orders (id),
CONSTRAINT book_id_FK FOREIGN KEY (book_id) REFERENCES book (id)
);
  • 表之间的结构:

image.png


设计Dao

public class OrderDaoImpl implements zhongfucheng.dao.OrderDao {

@Override
public void addOrder(Order order) {
QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());
String sql1 = "INSERT INTO orders(id,ordertime,user_id,state,price) VALUES(?,?,?,?,?)";
try {
//订单的基本信息
queryRunner.update(sql1, new Object[]{order.getId(), order.getOrdertime(), order.getUser_id(), order.isState(), order.getPrice()});

//订单项的信息
String sql2 = "INSERT INTO orderItem(id,price,quantity,order_id,book_id) VALUES(?,?,?,?,?)";

Set<OrderItem> items = order.getItems();

for (OrderItem item : items) {
queryRunner.update(sql2, new Object[]{item.getId(), item.getPrice(), item.getQuantity(), item.getOrder_id(), item.getBook_id()});
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

@Override
public Order findOrder(String id) {
QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

Order order;
try {
//找出订单的基本信息
String sql = "SELECT * FROM orders WHERE id=?";
order = (Order) queryRunner.query(sql, new BeanHandler(Order.class), new Object[]{id});

//找出订单的所有订单项
String sql2 = "SELECT * FROM orderItem WHERE order_id=?";
List<OrderItem> list = (List<OrderItem>) queryRunner.query(sql2, new BeanListHandler(OrderItem.class), new Object[]{order.getId()});

System.out.println("这是数据库拿到的list集合:"+list.size());


//将所有订单项装到订单里边
order.getItems().addAll(list);
System.out.println("这是数据库拿到的"+order.getItems().size());


//找出该订单是属于哪一个用户的
String sql3 = "SELECT * FROM orders o,user u WHERE o.user_id=u.id AND o.id=? ";
User user = (User) queryRunner.query(sql3, new BeanHandler(User.class), new Object[]{order.getId()});

order.setUser_id(user.getId());
return order;


} catch (SQLException e) {
throw new RuntimeException(e);
}
}


//更新订单的状态
public void updateState(String id) {

QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

String sql = "UPDATE orders SET state=? WHERE id=?";

try {
queryRunner.update(sql, new Object[]{true, id});
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

//查看已经发货或没发货的订单信息
public List<Order> getAllOrder(boolean state) {
QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

String sql = "SELECT * FROM orders WHERE state=? ";
try {
return (List<Order>) queryRunner.query(sql, new BeanListHandler(Order.class), new Object[]{state});
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

//通过用户的id查找用户的订单,可能不止一个
public List<Order> findUserOrder(String user_id) {
QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

String sql = "SELECT * FROM orders WHERE user_id=? ";

try {
return List<Order> queryRunner.query(sql, new BeanHandler(Order.class), new Object[]{user_id});

} catch (SQLException e) {
throw new RuntimeException(e);
}

}
}

二次更新

在编写dao的时候,尤其是Add方法。它是将所有数据都封装到Order对象上,然后取出数据,把数据插入到数据表中

  • 其实,我们的Order和OrderItem的操作可以分开。OrderItem也可以另外编写一个Dao,那么我们在插入完Order对象之后,得到Order对象返回的主键,再调用OrderItemDao的方法来插入OrderItem的数据,这样我觉得会让代码清晰一些。

  • 在OrderItemDao中接收的是一个List,因为我们一个订单会对应多个订单项。

抽取成DAO接口

public interface OrderDao {
void addOrder(Order order);

Order findOrder(String id);

List<Order> getAllOrder(boolean state);

void updateState(String user_id);

List<Order> findUserOrder(String user_id);
}

BussinessService

    private OrderDao orderDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.OrderDaoImpl", OrderDao.class);
public void createOrder(Cart cart, User user) {

//订单的基本信息
String order_id = WebUtils.makeId();
Order order = new Order();
order.setId(order_id);
order.setPrice(cart.getPrice());
order.setOrdertime(new Date());
order.setState(false);
order.setUser_id(user.getId());


//订单项的基本信息
//得到每个购物项,购物项就作为订单项
for (Map.Entry<String, CartItem> me : cart.getMap().entrySet()) {

OrderItem orderItem = new OrderItem();
CartItem cartItem = me.getValue();

orderItem.setId(WebUtils.makeId());
orderItem.setPrice(cartItem.getPrice());
orderItem.setBook_id(cartItem.getBook().getId());
orderItem.setQuantity(cartItem.getQuantity());
orderItem.setOrder_id(order_id);
order.getItems().add(orderItem);
}

orderDao.addOrder(order);

}

public Order findOrder(String user_id) {

return orderDao.findOrder(user_id);
}

public List<Order> getAllOrder(boolean state) {
return orderDao.getAllOrder(state);
}

public void sendOutOrder(String id) {

orderDao.updateState(id);
}

public List<Order> findUserOrder(String user_id) {
return orderDao.findUserOrder(user_id);
}

生成订单的Servlet

        BussinessServiceImpl service = new BussinessServiceImpl();

//检查该用户的购物车是否有商品
Cart cart = (Cart) request.getSession().getAttribute("cart");
if (cart == null) {
request.setAttribute("message", "您购物车没有商品,无法生成订单");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}

//如果有商品,得到当前用户
User user = (User) request.getSession().getAttribute("user");
service.createOrder(cart, user);
request.setAttribute("message", "订单已经生成了,准备好钱来收货把");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;

用户查询自己的订单Servlet

      查看订单
        BussinessServiceImpl service = new BussinessServiceImpl();

//检查该用户是否登陆了
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
request.setAttribute("message", "您还没登陆,等您登陆了再来看把");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}

//用户登陆了!
Order order = service.findUserOrder(user.getId());

//交给相对应的JSP 显示
request.setAttribute("order", order);
request.setAttribute("user",user);
request.getRequestDispatcher("/client/listOrder.jsp").forward(request, response);
return ;

显示订单数据的JSP

     您还没有下过任何订单!!                          下单人:            订单时间            订单状态            订单价钱                            ${user.username}            ${order.ordertime}            ${order.state==false?"未发货":"已发货"}            ${order.price}

后台查询订单的状况Servlet

  待处理订单  已发货订单
        BussinessServiceImpl service = new BussinessServiceImpl();
String state = request.getParameter("state");

if (state.equals("true")) {
List<Order> list = service.getAllOrder(true);
request.setAttribute("list",list);

} else if (state.equals("false")) {
List<Order> list = service.getAllOrder(false);
request.setAttribute("list", list);
}


request.getRequestDispatcher("/background/listOrder.jsp").forward(request, response);

显示订单状况的JSP

     还没有任何订单哦!                          下单人:            订单时间            订单状态            订单价钱            操作                                              ${order.user_id}                ${order.ordertime}                ${order.state==false?"未发货":"已发货"}                ${order.price}                                     查看详细信息                     删除

查看具体订单的详细信息Servlet

        BussinessServiceImpl service = new BussinessServiceImpl();

//得到用户想要查看详细信息的表单
String order_id = request.getParameter("order_id");

Order order = service.findOrder(order_id);

//将该order对象给相对应的JSP显示
request.setAttribute("order", order);
request.getRequestDispatcher("/background/listDetail.jsp").forward(request, response);

查看具体订单的详细信息JSP

           书籍的编号       价钱       数量       操作                             ${item.book_id}            ${item.price}            ${item.quantity}             发货

处理发货的Servlet

        BussinessServiceImpl service = new BussinessServiceImpl();
String id = request.getParameter("id");

service.sendOutOrder(id);
request.setAttribute("message", "已发货!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;

添加权限控制

目前为止,我们已经学习了动态代理技术和注解技术了。于是我们想要为之前的bookStore项目添加权限控制.....

只有用户有权限的时候,后台管理才可以进行相对应的操作.....


实现思路

image.png

之前我们做权限管理系统的时候,是根据用户请求的URI来判断该链接是否需要权限的。这次我们使用动态代理的技术和注解来判断:用户调用该方法时,检查该方法是否需要权限...

根据MVC模式,我们在web层都是调用service层来实现功能的。那么我们具体的思路是这样的:

  • web层调用service层的时候,得到的并不是ServiceDao对象,而是我们的代理对象

  • 在service层中的方法添加注解,如果方法上有注解,那么说明调用该方法需要权限...

  • 当web层调用代理对象方法的时候,代理对象会判断该方法是否需要权限,再给出相对应的提示....


设计实体、数据库表

上次我们做的权限管理系统是引入了角色这个概念的,这次主要为了练习动态代理和注解技术,就以简单为主,不引入角色这个实体。直接是用户和权限之间的关系了。

Privilege实体

public class Privilege {

private String id ;
private String name;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

数据库表

  • privilege表

CREATE TABLE privilege (

id VARCHAR(40) PRIMARY KEY,
name VARCHAR(40)

);

privilege和user是多对多的关系,于是使用第三方表来维护他们的关系

  • user_privilege表

CREATE TABLE user_privilege (
privilege_id VARCHAR(40),
user_id VARCHAR(40),

PRIMARY KEY (privilege_id, user_id),
CONSTRAINT privilege_id_FK FOREIGN KEY (privilege_id) REFERENCES privilege(id),
CONSTRAINT user_id_FK1 FOREIGN KEY (user_id) REFERENCES user(id)

);

添加测试数据

为了方便,直接添加数据了。就不写详细的DAO了。

  • 在数据库中添加了两个权限

image.png

  • 为id为1的user添加了两个权限

image.png


编写DAO

后面在动态代理中,我们需要检查该用户是否有权限...那么就必须查找出该用户拥有的哪些权限。再看看用户有没有相对应的权限

    //查找用户的所有权限
public List<Privilege> findUserPrivilege(String user_id) {
QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

String sql = "SELECT p.* FROM privilege p, user_privilege up WHERE p.id = up.privilege_id AND up.user_id = ?";
try {
return (List<Privilege>) queryRunner.query(sql, new Object[]{user_id}, new BeanListHandler(Privilege.class));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

抽取到接口上

    List<Privilege> findUserPrivilege(String user_id);

注解模块

  • 编写注解

@Retention(RetentionPolicy.RUNTIME)
public @interface permission {
String value();
}
  • 在Service层方法中需要权限的地方添加注解CategoryServiceImpl

    @permission("添加分类")
/*添加分类*/
public void addCategory(Category category) {
categoryDao.addCategory(category);
}


/*查找分类*/
public void findCategory(String id) {
categoryDao.findCategory(id);
}

@permission("查找分类")
/*查看分类*/
public List<Category> getAllCategory() {
return categoryDao.getAllCategory();
}

抽取Service

把Service的方法抽取成ServiceDao。在Servlet中,也是通过ServiceFactory来得到Service的对象【和DaoFactory是类似的】

CategoryService

    @permission("添加分类")
/*添加分类*/ void addCategory(Category category);

/*查找分类*/
void findCategory(String id);

@permission("查找分类")
/*查看分类*/ List<Category> getAllCategory();

ServiceFactory

public class ServiceDaoFactory {

private static final ServiceDaoFactory factory = new ServiceDaoFactory();

private ServiceDaoFactory() {
}

public static ServiceDaoFactory getInstance() {
return factory;
}


//需要判断该用户是否有权限
public <T> T createDao(String className, Class<T> clazz, final User user) {

System.out.println("添加分类进来了!");

try {
//得到该类的类型
final T t = (T) Class.forName(className).newInstance();
//返回一个动态代理对象出去
return (T) Proxy.newProxyInstance(ServiceDaoFactory.class.getClassLoader(), t.getClass().getInterfaces(), new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, PrivilegeException {
//判断用户调用的是什么方法
String methodName = method.getName();
System.out.println(methodName);

//得到用户调用的真实方法,注意参数!!!
Method method1 = t.getClass().getMethod(methodName,method.getParameterTypes());

//查看方法上有没有注解
permission permis = method1.getAnnotation(permission.class);

//如果注解为空,那么表示该方法并不需要权限,直接调用方法即可
if (permis == null) {
return method.invoke(t, args);
}

//如果注解不为空,得到注解上的权限
String privilege = permis.value();

//设置权限【后面通过它来判断用户的权限有没有自己】
Privilege p = new Privilege();
p.setName(privilege);

//到这里的时候,已经是需要权限了,那么判断用户是否登陆了
if (user == null) {

//这里抛出的异常是代理对象抛出的,sun公司会自动转换成运行期异常抛出,于是在Servlet上我们根据getCause()来判断是不是该异常,从而做出相对应的提示。
throw new PrivilegeException("对不起请先登陆");
}

//执行到这里用户已经登陆了,判断用户有没有权限
Method m = t.getClass().getMethod("findUserPrivilege", String.class);
List<Privilege> list = (List<Privilege>) m.invoke(t, user.getId());

//看下权限集合中有没有包含方法需要的权限。使用contains方法,在Privilege对象中需要重写hashCode和equals()
if (!list.contains(p)) {
//这里抛出的异常是代理对象抛出的,sun公司会自动转换成运行期异常抛出,于是在Servlet上我们根据getCause()来判断是不是该异常,从而做出相对应的提示。
throw new PrivilegeException("您没有权限,请联系管理员!");
}

//执行到这里的时候,已经有权限了,所以可以放行了
return method.invoke(t, args);
}
});

} catch (Exception e) {
new RuntimeException(e);
}
return null;
}
}

PrivilegeExcetption

当用户没有登陆或者没有权限的时候,我们应该给用户一些友好的提示....于是我们自定义了PrivilegeException

public class PrivilegeException extends Exception {

public PrivilegeException() {
super();
}

public PrivilegeException(String message) {
super(message);
}

public PrivilegeException(String message, Throwable cause) {
super(message, cause);
}

public PrivilegeException(Throwable cause) {
super(cause);
}
}

我们继承的是Exception,通过方法名抛出去。但是我们是通过代理对象调用方法的,于是sun公司的策略就是把它们转换成运行期异常抛出去

因此,我们就在Servlet上得到异常,再给出友好的提示。。


效果:

  • 没有登陆的时候:

image.png

  • 登陆了,但是没有相对应的权限的时候

  • 登陆了,并且有权限

image.png

要点总结

该权限控制是十分优雅的,只要我在Service层中添加一个注解...那么当web层调用该方法的时候就需要判断用户有没有该权限....

  1. 外界调用Service层的方法是代理调用invoke()方法,我们在invoke()方法可以对其进行增强!

  2. invoke()方法内部就是在查询调用该方法上有没有注解,如果没有注解,就可以直接调用。如果有注解,那么就得到注解的信息,判断该用户有没有权限来访问这个方法

  3. 在反射具体方法的时候,必须记得要给出相对应的参数!

  4. 在invoke()方法抛出的编译时期异常,java会自动转换成运行期异常进行抛出...

  5. 使用contains()方法时,就要重写该对象的hashCode()和equals()


更多相关文章

  1. 文件权限管理剖析
  2. SpringSecurity实现动态管理权限(三)
  3. k8s rbac 权限管理控制创建过程+理论知识
  4. 在Access中利用Jquery技术实现专业的界面和权限控制的通用程序
  5. 您试图显示配置为只允许执行和脚本权限的目录中的 HTML 页
  6. 在京东上6-24日购买6台笔记本7天无理由 退货 退不了 把订单编号
  7. 权限被拒绝:/var/www/abc/.htaccess pcfg_openfile:无法检查htacce
  8. 设计多级用户权限系统
  9. 本机PHP函数将授予我直接访问字符串部分而无需创建临时数组的权

随机推荐

  1. 《PHP核心技术与最佳实践》P37中间有一句
  2. php把从数据库读取出来的数据存放到数组
  3. php 谈谈我对session, cookies和jwt的理
  4. 当我将它移动到另一台服务器时,计数器将无
  5. 案例:用Redis来存储关注关系(php版)
  6. 如何在进行单元测试时覆盖php://输入
  7. 如何在mysql中配置区分大小写的数据库标
  8. 在两个不同的地方分割/爆炸一个PHP字符串
  9. 如何用jQuery AJAX调用发送所有当前的pos
  10. PHP实例————万年历