要登錄後才能購買,所以咱們先寫購買模塊.javascript
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 );
/** * 用戶的登陸註冊模塊 * 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); } } }
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()); } }
public interface UserDao { void register(User user); User login(String username, String password); User find(String id); }
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); }
<div id="User"> 用戶名:<input type="text" name="username"> 密碼:<input type="password" name="password"> <button name="login">登錄</button> <button name="register">註冊</button> </div>
#body { position: relative; } #user { position: absolute; margin-top: 130px; margin-left: 1364px; }
當點擊登錄按鈕的時候,把數據帶過去給Servlet,讓Servlet調用BusinessService方法,實現登錄。註冊同理.....所以,咱們須要用到JavaScript代碼css
<c:if test="${user==null}" > <div id="User"> 用戶名:<input type="text" id="username"> 密碼:<input type="password" id="password"> <button name="login" onclick="login()">登錄</button> <button name="register" onclick="register()">註冊</button> </div> </c:if> <c:if test="${user!=null}" > <div id="User"> 歡迎您:${user.username} <a href="${pageContext.request.contextPath}/UserServlet?method=Logout">註銷</a> </div> </c:if>
<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>
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); }
在顯示圖書的時候,順便添加購買的超連接html
<li><a href="#">購買</a></li>
若是不清楚爲何這樣設計,可參考我以前的博文:http://blog.csdn.net/hon_3y/article/details/56481439#t5java
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; } }
<li><a href="${pageContext.request .contextPath}/BuyServlet?book_id=${book.id}">購買</a></li>
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);
//先判斷該用戶是否登錄了 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);
<c:if test="${empty(cart.map)}"> 您尚未購買過任何商品哦!!! </c:if> <table border="1px"> <c:if test="${!empty(cart.map)}"> <h1>您購物車下有以下的商品:</h1><br> <tr> <td>書名:</td> <td>做者:</td> <td>數量:</td> <td>價錢:</td> </tr> <c:forEach items="${cart.map}" var="cartItme"> <tr> <td>${cartItme.value.book.name}</td> <td>${cartItme.value.book.author}</td> <td>${cartItme.value.quantity}</td> <td>${cartItme.value.price}</td> </tr> </c:forEach> </c:if> </table>
在前臺用戶界面中,當用戶要把購物車付款時,應該提供生成訂單的超連接....mysql
訂單應該包含id,收貨人信息,下單的時間,訂單的總價,訂單的狀態【有無發貨】..而不該該包含商品的信息的。商品的信息用一個專門的」訂單項「來表示web
一個訂單對應多個訂單項,這是一對多的關係!sql
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) );
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對象上,而後取出數據,把數據插入到數據表中session
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); }
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); }
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;
<a href="${pageContext.request.contextPath}/LookOrder" target="body">查看訂單</a>
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 ;
<c:if test="${order==null}"> 您尚未下過任何訂單!! </c:if> <c:if test="${order!=null}"> <table border="1px"> <tr> <td>下單人:</td> <td>訂單時間</td> <td>訂單狀態</td> <td>訂單價錢</td> </tr> <tr> <td>${user.username}</td> <td>${order.ordertime}</td> <td>${order.state==false?"未發貨":"已發貨"}</td> <td>${order.price}</td> </tr> </table> </c:if>
<a href="${pageContext.request.contextPath}/OrderServlet?state=false" target="body">待處理訂單</a><br> <a href="${pageContext.request.contextPath}/OrderServlet?state=true" target="body">已發貨訂單</a><br>
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);
<c:if test="${empty(list)}"> 尚未任何訂單哦! </c:if> <c:if test="${!empty(list)}"> <table border="1px"> <tr> <td>下單人:</td> <td>訂單時間</td> <td>訂單狀態</td> <td>訂單價錢</td> <td>操做</td> </tr> <c:forEach items="${list}" var="order"> <tr> <td>${order.user_id}</td> <td>${order.ordertime}</td> <td>${order.state==false?"未發貨":"已發貨"}</td> <td>${order.price}</td> <td> <a href="${pageContext.request.contextPath}/orderItemServlet?order_id=${order.id}">查看詳細信息</a> <a href="#">刪除</a> </td> </tr> </c:forEach> </table> </c:if>
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);
<table border="1px"> <tr> <td>書籍的編號</td> <td>價錢</td> <td>數量</td> <td>操做</td> </tr> <c:forEach items="${order.items}" var="item"> <tr> <td>${item.book_id}</td> <td>${item.price}</td> <td>${item.quantity}</td> <td><a href="${pageContext.request.contextPath}/SendOutServlet?id=${order.id}">發貨</a></td> </tr> </c:forEach> </table>
BussinessServiceImpl service = new BussinessServiceImpl(); String id = request.getParameter("id"); service.sendOutOrder(id); request.setAttribute("message", "已發貨!"); request.getRequestDispatcher("/message.jsp").forward(request, response); return;
目前爲止,咱們已經學習了動態代理技術和註解技術了。因而咱們想要爲以前的bookStore項目添加權限控制.....jsp
只有用戶有權限的時候,後臺管理才能夠進行相對應的操做.....
以前咱們作權限管理系統的時候,是根據用戶請求的URI來判斷該連接是否須要權限的。此次咱們使用動態代理的技術和註解來判斷:用戶調用該方法時,檢查該方法是否須要權限...
根據MVC模式,咱們在web層都是調用service層來實現功能的。那麼咱們具體的思路是這樣的:
上次咱們作的權限管理系統是引入了角色這個概念的,此次主要爲了練習動態代理和註解技術,就以簡單爲主,不引入角色這個實體。直接是用戶和權限之間的關係了。
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; } }
CREATE TABLE privilege ( id VARCHAR(40) PRIMARY KEY, name VARCHAR(40) );
privilege和user是多對多的關係,因而使用第三方表來維護他們的關係
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了。
後面在動態代理中,咱們須要檢查該用戶是否有權限...那麼就必須查找出該用戶擁有的哪些權限。再看看用戶有沒有相對應的權限
//查找用戶的全部權限 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(); }
@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的方法抽取成ServiceDao。在Servlet中,也是經過ServiceFactory來獲得Service的對象【和DaoFactory是相似的】
@permission("添加分類") /*添加分類*/ void addCategory(Category category); /*查找分類*/ void findCategory(String id); @permission("查找分類") /*查看分類*/ List<Category> getAllCategory();
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; } }
當用戶沒有登錄或者沒有權限的時候,咱們應該給用戶一些友好的提示....因而咱們自定義了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上獲得異常,再給出友好的提示。。
該權限控制是十分優雅的,只要我在Service層中添加一個註解...那麼當web層調用該方法的時候就須要判斷用戶有沒有該權限....