Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Mô hình MVC và 1 ví dụ ứng dụng

1. Thế nào là mô hình 1?

Ngày xưa các bạn lập trình một trang jsp, php hay asp, các bạn thường đan xen các mã html cùng với các mã jsp, php, hay asp. Do vậy, có những khó khăn sau có thể gặp phải:

  • Người thiết kế giao diện cũng cần phải biết các ngôn ngữ lập trình, hoặc bạn phải trực tiếp thiết kế chúng.
  • Việc bảo trì chúng thường rất khó khăn, vì một phần các mã chương trình lẫn lộn với mã html.
  • Khi có lỗi xảy ra, việc tìm ra lỗi và định vị ỗi cũng là một vấn đề khó khăn.
  • Và còn nhiều những khó khăn khác …

Việc lập trình như trên, người ta gọi là mô hình lập trình 1, hay là mô hình lập trình cổ điển.

model1

2. Thế nào là mô hình 2?

Để khắc phục các khó khăn trên, người ta đưa ra mô hình 2 hay còn gọi là mô hình MVC (Model-View-Controllor). Tức là: Tương ứng với một trang JSP ngày xưa, bây giờ người ta tách nó ra làm ba thành phần: Mô hình – Khung nhìn – Bộ điều khiển. Các thành phần trên làm việc như sau:

Mô hình: Mô hình là các lớp java có nhiệm vụ:

  • Nhận các yêu cầu từ khung nhìn
  • Thi hành các yêu cầu đó (tính toán, kết nối CSDL …)
  • Trả về các giá trị tính toán cho View.

Khung nhìn: Bao gồm các mã tương tự như JSP để hiển thị form nhập liệu, các kết quả trả về từ Mô hình…

Bộ điều khiển: Đồng bộ hoá giữa Khung nhìn và Mô hình. Tức là với một trang JSP này thì sẽ tương ứng với lớp java nào để xử lý nó và ngược lại, kết quả sẽ trả về trang jsp nào.

Như vậy, chúng ta có thể tách biệt được các mã java ra khỏi mã html. Do vậy, nó đã giải quyết được các khó khăn đã nêu ra trong Mô hình 1. Người thiết kế giao diện và người lập trình java có thể mang tính chất độc lập tương đối. Việc debug hay bảo trì sẽ dễ dàng hơn, việc thay đổi các theme của trang web cũng dễ dàng hơn …

model1

Một ví dụ dễ thấy nhất của kiến trúc MVC là cách hiện thực của 1 đối tượng GUI của gói swing. Một đối tượng đồ họa (GUI Component) bao gồm 3 thành phần cơ bản: Model, View, và Controller. Model có trách nhiệm đối với toàn bộ dữ liệu cũng như trạng thái của đối tượng đồ họa. View chính là thể hiện trực quan của Model, hay nói cách khác chính là giao diện của đối tượng đồ họa. Và Controller điều khiển việc tương tác giữa đối tượng đồ họa với người sử dụng cũng như những đối tượng khác.

Khi người sử dụng hoặc những đối tượng khác cần thay đổi trạng thái của đối tượng đồ họa, nó sẽ tương tác thông qua Controller của đối tượng đồ họa. Controller sẽ thực hiện việc thay đổi trên Model. Khi có bất kỳ sự thay đổi nào ở xảy ra ở Model, nó sẽ phát thông điệp (broadcast message) thông báo cho View và Controller biết. Nhận được thông điệp từ Model, View sẽ cập nhật lại thể hiện của mình, đảm bảo rằng nó luôn là thể hiện trực quan chính xác của Model. Còn Controller, khi nhận được thông điệp từ Model, sẽ có những tương tác cần thiết phản hồi lại người sử dụng hoặc các đối tượng khác.

Lấy ví dụ một GUI Component đơn giản là Checkbox. Checkbox có thành phần Model để quản lý trạng thái của nó là check hay uncheck, thành phần View để thể hiện nó với trạng thái tương ứng lên màn hình, và thành phần Controller để xử lý những sự kiện khi có sự tương tác của người sử dụng hoặc các đối tượng khác lên Checkbox. Khi người sử dụng nhấn chuột vào Checkbox, thành phần Controller của Checkbox sẽ xử lý sự kiện này, yêu cầu thành phần Model thay đổi dữ liệu trạng thái. Sau khi thay đổi trạng thái, thành phần Model phát thông điệp đến thành phần View và Controller. Thành phần View của Checkbox nhận được thông điệp sẽ cập nhật lại thể hiện của Checkbox, phản ánh chính xác trạng thái Checkbox do Model lưu giữ. Thành phần Controller nhận được thông điệp do Model gởi tới sẽ có những tương tác phản hồi với người sử dụng nếu cần thiết.

Tuy nhiên, việc sử dụng mô hình MVC model 2 một cách hoàn toàn cứng nhắc (phần “Điều khiển” chỉ dùng servlet, phần “Hiển thị” chỉ dùng JSP )sẽ dẫn đến một vài trường hợp kém hiệu quả, nhất là khi các yêu cầu từ trình duyệt web chỉ đòi hỏi việc hiển thị thông tin. Trong trường hợp này, gửi thẳng yêu cầu hiển thị từ trình duyệt web tới trang JSP sẽ hiệu quả hơn.

Sau đây là 1 ví dụ ứng dụng mô hình MVC để tạo 1 giỏ hàng:
Bạn phải có cơ sở dữ liệu như hình:
db

Cấu trúc thư mục sau khi hoàn thành sẽ như sau:
cautruc
Các bước tiến hành như sau:
Trong thư mục webapps của thư mục cài đặt Tomcat, tạo folder có tên ShoppingCart

1>Tạo trang MyEShop.jsp có nội dung sau:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="shopping.*" %>
<%@page import="java.util.ArrayList" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <title>My E-Shop</title>
        <script type="text/javascript">
            function kt(){
                var s=document.getElementById("sl").value;
                if(isNaN(s) || s<=0)
                    return false;
                return true;
            }
        </script>
    </head>
    <body>
        <h1>GIỎ HÀNG ONLINE - MVC</h1>
        <%
            DBActions db = new DBActions();
            ArrayList<Sanpham> dssp = db.getAllProducts();
        %>
        <form action="ControllerServlet">
            Hãy chọn món hàng cần mua:
            <select name="monhang">
                <%
            for (Sanpham sp : dssp) {%>
                <option value="<%=sp.getMsSP()%>"><%=sp.getTenSP()%></option>
                <%}%>
            </select>
            Số lượng<input name="soluong" value="0" id="sl"/>
            <input type="hidden" name="action" value="muahang"/>
            <input type="submit" value="Mua hàng" onclick="return kt()"/>
        </form>
		<br/>
        <jsp:include page="MyECart.jsp" flush="true"/>
    </body>
</html>

2>Tạo trang MyECart.jsp có nội dung sau

<%-- 
    Document   : giohang
    Author     : VoVanHai
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="java.util.ArrayList" %>
<%@page import="shopping.*" %>
<%
   Object obj=session.getAttribute("giohang");
   if(obj!=null){
       Giohang giohang=(Giohang)obj;
       ArrayList<Monhang>dssp=giohang.getGiohang();
	   if(dssp.size()>0){
%>
<table align="center" border="1" width="95%">
    <tr>
        <th>STT</th>
        <th>Tên món hàng</th>
        <th>Số lượng</th>
        <th>Đơn giá</th>
        <th>Thành tiền</th>
        <th></th>
    </tr>
    <%int i=1;
    for(Monhang mh:dssp){
        String ms=mh.getSanpham().getMsSP();
        String ten=mh.getSanpham().getTenSP();
        double dg=mh.getSanpham().getDongia();
        int sl=mh.getSoluong();
        %>
        <tr>
            <td><%=(i++)%></td>
            <td><%=ten%></td>
            <td><%=dg%></td>
            <td><%=sl%></td>
            <td><%=dg*sl%></td>
            <td>
                <form action="ControllerServlet" method="post">
                    <input type="hidden" name="action" value="trahang"/>
                    <input type="hidden" name="mssp" value="<%=ms%>"/>
                    <input type="submit" value="Trả hàng"/>
                </form>
            </td>
        </tr>
    <%}%>
    </table>
    <br/>
        <center>
            <form action="ControllerServlet">
                <input type="hidden" name="action" value="checkout"/>
                <input type="submit" value="Check out"/>
            </form>
        </center>
   <%}
   }
%>

3>Tạo trang Checkout.jsp có nội dung sau

<%-- 
    Document   : Checkout
    Created on : 16-03-2011, 17:58:41
    Author     : VoVanHai
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="java.util.ArrayList" %>
<%@page import="shopping.*" %>
<%
   Object obj=session.getAttribute("giohang");
   if(obj!=null){
       Giohang giohang=(Giohang)obj;
       ArrayList<Monhang>dssp=giohang.getGiohang();
%>
<h1 align="center">TÍNH TIỀN</h1>
<table align="center" border="1" width="95%">
    <tr>
        <th>STT</th>
        <th>Tên món hàng</th>
        <th>Số lượng</th>
        <th>Đơn giá</th>
        <th>Thành tiền</th>
    </tr>
    <%int i=1;
    for(Monhang mh:dssp){
        String ms=mh.getSanpham().getMsSP();
        String ten=mh.getSanpham().getTenSP();
        double dg=mh.getSanpham().getDongia();
        int sl=mh.getSoluong();
        %>
        <tr>
            <td><%=(i++)%></td>
            <td><%=ten%></td>
            <td><%=dg%></td>
            <td><%=sl%></td>
            <td><%=dg*sl%></td>
        </tr>
    <%}%>
    <tr>
        <td align="right" colspan="5" ><b>Tổng tiền:<%=giohang.Tongtien()%></b></td>
    </tr>
    </table>
	<br/>
	<a href="MyEShop.jsp">Nhấn vào đây để mua thêm hàng</a>
   <%}
%>

4>Trong thư mục classes tạo các file java có nội dung như sau:

File Sanpham.java:

package shopping;

import java.io.Serializable;

/**
 * Lớp đặc tả cho 1 sản phẩm
 * @author VoVanHai
 */
public class Sanpham  implements Serializable{
    private String msSP;
    private String tenSP;
    private float dongia;

    public Sanpham(String msSP, String tenSP, float dongia) {
        this.msSP = msSP;
        this.tenSP = tenSP;
        this.dongia = dongia;
    }

    public float getDongia() {
        return dongia;
    }

    public void setDongia(float dongia) {
        this.dongia = dongia;
    }

    public String getMsSP() {
        return msSP;
    }

    public void setMsSP(String msSP) {
        this.msSP = msSP;
    }

    public String getTenSP() {
        return tenSP;
    }

    public void setTenSP(String tenSP) {
        this.tenSP = tenSP;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Sanpham other = (Sanpham) obj;
        if ((this.msSP == null) ? (other.msSP != null) : !this.msSP.equals(other.msSP)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 19 * hash + (this.msSP != null ? this.msSP.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return msSP+";"+ tenSP;
    }    
}

File Monhang.java:

package shopping;

import java.io.Serializable;

/**
 * Một món hàng trong giỏ hàng
 * @author VoVanHai
 */
public class Monhang implements Serializable{
    private Sanpham sanpham;
    private int soluong;

    public Monhang(Sanpham sanpham, int soluong) {
        this.sanpham = sanpham;
        this.soluong = soluong;
    }

    public Sanpham getSanpham() {
        return sanpham;
    }

    public void setSanpham(Sanpham sanpham) {
        this.sanpham = sanpham;
    }

    public int getSoluong() {
        return soluong;
    }

    public void setSoluong(int soluong) {
        this.soluong = soluong;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Monhang other = (Monhang) obj;
        if (this.sanpham != other.sanpham && (this.sanpham == null || !this.sanpham.equals(other.sanpham))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + (this.sanpham != null ? this.sanpham.hashCode() : 0);
        return hash;
    }
}

File Giohang.java:

package shopping;

import java.io.Serializable;
import java.util.ArrayList;

/**
 * Đặc tả một giỏ hàng
 * @author VoVanHai
 */
public class Giohang  implements Serializable{

    private ArrayList<Monhang> giohang;

    public Giohang() {
        giohang = new ArrayList<Monhang>();
    }

    /**
     * Thêm một món hàng vào giỏ
     * @param mh món hàng cần thêm
     */
    public void ThemMonHang(Monhang mh) {
        //nếu có món này trong giỏ thì cập nhật lại số lượng
        if (giohang.contains(mh)) {
            Monhang m = giohang.get(giohang.indexOf(mh));
            m.setSoluong(m.getSoluong() + mh.getSoluong());
        } else//nếu chưa có món này trong giỏ thì thêm mới
            giohang.add(mh);
    }

    /**
     * Trả món hàng khỏi giỏ
     * @param mh là món hàng muốn trả
     */
    public void XoaMonhang(Monhang mh) {
        if (giohang.contains(mh)) {
            giohang.remove(mh);
        }
    }

    /**
     * Lấy giỏ hàng
     * @return
     */
    public ArrayList<Monhang> getGiohang() {
        return giohang;
    }
    /**
     * TÍnh tổng tiền của giò hàng
     * @return số tiền phải trả của giỏ hàng
     */
    public double Tongtien(){
        double tt=0d;
        for(Monhang mh:giohang){
            tt+=mh.getSanpham().getDongia()*mh.getSoluong();
        }
        return tt;
    }
}

File DBActions.java:

package shopping;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

/**
 * Các công việc liên quan đến cơ sở dữ liệu.
 * @author VoVanHai
 */
public class DBActions {

    private Connection con;

    public DBActions() throws Exception {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        con = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=ProductDB", "sa", "");
    }

    /**
     * Lấy sản phẩm khi biết mã số sản phẩm
     * @param ms mã số sản phẩm
     * @return sản phẩm cần lấy hoặc null truong trường hợp sp không tồn tại
     * @throws Exception
     */
    public Sanpham getSanPham(String ms) throws Exception {
        Sanpham sp = null;
        Statement stmt = con.createStatement();
        String sql = "select * from sanpham where mssp ='" + ms + "'";
        ResultSet rs = stmt.executeQuery(sql);
        if (rs.next()) {
            String mssp = rs.getString("mssp");
            String ten = rs.getString("tenSP");
            float dg = rs.getFloat("dongia");
            sp = new Sanpham(mssp, ten, dg);
        }
        return sp;
    }

    /**
     * Lấy tât cả sản phẩm
     * @return danh sách sản phẩm
     * @throws Exception
     */
    public ArrayList<Sanpham> getAllProducts() throws Exception {
        ArrayList<Sanpham> ds = new ArrayList<Sanpham>();
        ResultSet rs = null;
        Statement stmt = con.createStatement();
        String sql = "select * from sanpham";
        rs = stmt.executeQuery(sql);
        while(rs.next()){
            String mssp = rs.getString("mssp");
            String ten = rs.getString("tenSP");
            float dg = rs.getFloat("dongia");
            ds.add(new Sanpham(mssp, ten, dg));
        }
        return ds;
    }
}

File ControllerServlet.java:

package shopping;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Lớp Controller quản lý các tác vụ tập trung
 * @author VoVanHai
 */
public class ControllerServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            HttpSession session = request.getSession(false);
            DBActions db = new DBActions();
            Giohang giohang = null;
            Object obj = session.getAttribute("giohang");
            if (obj != null) {
                giohang = (Giohang) obj;
            }
            String action = request.getParameter("action");

            if (action.equals("muahang")) {
                String msSP = request.getParameter("monhang");//lấy ms sản phẩm được chọn
                int soluong = Integer.parseInt(request.getParameter("soluong"));
                Sanpham sp = db.getSanPham(msSP);//Lấy sản phẩm từ cơ sở dữ liệu
                Monhang mh = new Monhang(sp, soluong);
                if (giohang == null) {//mua lần đầu
                    giohang = new Giohang();
                }
                giohang.ThemMonHang(mh);
            } else if (action.equals("trahang")) {
                String msSP = request.getParameter("mssp");//lấy ms sản phẩm cần xóa
                Monhang mh=new Monhang(new Sanpham(msSP, "", 0f), 0);
                giohang.XoaMonhang(mh);
            } else if (action.equals("checkout")) {
                response.sendRedirect("Checkout.jsp");
            }

            session.setAttribute("giohang", giohang);

            //chuyển lại trang mua hàng
            response.sendRedirect("MyEShop.jsp");
        } catch (Exception e) {
            //e.printStackTrace();
            response.getWriter().print(e.getMessage());
        }
    }
}

5>Biên dịch các tập tin tạo ở bước 4

Dùng command-line :

javac -d . -classpath "e:\javaSoft\apache-tomcat-6.0.20\lib\servlet-api.jar" -encoding "UTF-8" *.java

(Chú ý thay đổi đường dẫn đến thư mục cài đặt Tomcat của bạn)

6>Trong thư mục WEB-INF tạo file web.xml có nội dung sau:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>ControllerServlet</servlet-name>
        <servlet-class>shopping.ControllerServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ControllerServlet</servlet-name>
        <url-pattern>/ControllerServlet</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>MyEShop.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

7>copy file driver của ms sql server vào thư mục lib
File này có thể tìm thấy ở trang của microsoft.
8>Mở Web Browser, nhập địa chỉ: http://localhost:8080/MVC_ShoppingCart/MyEShop.jsp

ketqua

Resources: Source code

Chúc các bạn thành công!


29 Responses to “Mô hình MVC và 1 ví dụ ứng dụng”

  1. tien long said

    Chào anh!Em có đọc topic này và chạy thử ví dụ này rồi.Em có ý kiến như sau:
    Như vậy ứng với ví dụ trên và dựa vào định nghĩa mô hình MVC, thì trang EShop.jsp,Cart.jsp;Checkout.jsp đóng vai trò là View; Còn File ShoppingServlet sẽ đóng vai trò là Model vì nó xử lý các yêu cầu mà EShop.jsp và Cart,jsp gửi tới, nó còn đóng vai trò là Controller ví nó sẽ trả kết quả tương ứng với trang nào ứng với yêu cầu đó.
    Cho em hỏi là :
    Em hiểu như thế có đúng không
    Nếu đúng:
    Như thế 1 file ShoopingServlet đóng 2 vai trò như thế có còn đúng với mục đích của MVC là tách biệt các trang ra từng phần trong MVC(1 file java ko thể đóng 2 vai trò)

  2. tien long said

    Thank you too! Em có thêm nhận xét sau: Đúng theo lý thuyết và đinh nghĩa của MVC trên trang chủ của Sun và tham khảo ý kiến nhiều người rùi thì Model chỉ chứa các Bean để represent data từ thế giới thực như ví dụ trên thì Model chỉ có Bean là file CD.java . Nhưng trong trang web của javaworld có ghi thì Model Cart.jsp và Checkout.jsp nữa (thật vậy trong code của 2 file này đều có xử lý thông tin).Như thế cái ví dụ trên chỉ đúng về mặt khái niệm chứ chưa rõ ràng về mặt hình thức.Hình thức ở đây là sự tách biệt code rõ ràng

  3. vovanhai said

    Việc sử dụng mô hình MVC model 2 một cách hoàn toàn cứng nhắc (phần “Điều khiển” chỉ dùng servlet, phần “Hiển thị” chỉ dùng JSP )sẽ dẫn đến một vài trường hợp kém hiệu quả, nhất là khi các yêu cầu từ trình duyệt web chỉ đòi hỏi việc hiển thị thông tin. Trong trường hợp này, gửi thẳng yêu cầu hiển thị từ trình duyệt web tới trang JSP sẽ hiệu quả hơn. Bởi thế nên không phải lúc nào cũng cứng nhắc cả. Tôi cũng mới vừa cập nhật lại bài viết, với ví dụ về swing component thì có lẽ là 1 implements hoàn toàn nhất cho mô hình này.:-)

  4. remoter said

    Sao khi em compile file ShoppingServlet no bao ko tim thay javax.servlet vay?

  5. phải set classpath đến tập tin servlet-api.jar trong %TOMCAT_HOME%\lib.

  6. Văn Ngọc said

    Chào anh : em có 2 bài tập về nhà Thiết kế theo mô hình MVC .
    – bài một là :
    “Memory Game
    Trò chơi “ghép hình” nhằm mục đích giúp luyện trí nhớ, thị giác, … cho trẻ em. Trò chơi gồm một tập các cặp hình giống nhau của các loài động vật được xáo trộn ngẫu nhiên, và đặt úp vào một lưới chữ nhật. Khi bắt đầu trò chơi, chương trình sẽ hiển thị tất cả các hình trên lưới trong một thời gian khoảng thời gian vừa đủ nào đó để người chơi quan sát và ghi nhớ các hình. Người chơi sẽ lần lượt lật tìm và ghép các cặp hình giống nhau cho đến hết. Nếu tìm được cặp hình giống nhau nào, thì hình ở các ô đó sẽ để lộ ra và người chơi sẽ được cộng 10 điểm thưởng. Nếu hình ghép không giống nhau sẽ bị trừ 2 điểm. Hãy cố gắng lật hết các ô với số điểm thưởng nhiều nhất có thể!
    Để đơn giản trong thiết kế chương trình, các hình sẽ được thể hiện bằng tên của con vật, và giao diện có thể thiết kế đơn giản như ví dụ sau với lưới có kích thước 4×4:

    + Chọn nút Start để bắt đầu chương trình bằng cách hiển thị tất cả hình các con vật trong khoảng thới gian vừa đủ để người chơi quan sát và ghi nhớ
    + Lật một cặp hình đúng
    + Lật cặp hình kế tiếp

    chọn Cancel để kết thúc lượt chơi
    Thiết kế và cài đặt chương trình thỏa mãn các yêu cầu sau:
    1) Dùng mẫu Model-View-Controler (dùng adapter hay observer đều được)
    2) Chương trình có thể mở rộng bằng cách thêm vào các ô phần thưởng (dưới dạng điểm thưởng) hoặc điểm phạt. ”

    - hai là
    Máy bán đồ uống
    Máy bán đồ uống được mô hình để bán 3 kiểu đồ uống. Máy bán có thể nhận các đơn vị tiền 10, 100 và 500. Tất cả các đồ uống đều có giá 110 đơn vị. Nếu số tiền còn lại sau khi chọn một đồ uống vẫn còn đủ, thì đồ uống khác có thể được chọn. Máy chỉ trả lại tiền khi nút xoá cancel được nhấn. Việc trả lại tiền cũng có thể được tiến hành nếu người mua quyết định không mua đồ uống nữa. Phần hiển thị chỉ ra số tiền đã được đưa vào để cho phép người mua biết mình đã đưa vào bao nhiêu tiền. Khi một đồ uống đã hết, thì một hiển thị “Empty” được trình bày cho loại đồ uống đó và người mua không thể chọn được. Nếu đồ uống đã hết

    Thiết kế dùng State parttern ,observer

    Em sắp phải nộp rồi , nếu không đủ 2 bài thì cấm thi luôn …vây hôm nay em đưa lên diễn dàn nhờ anh , hay bất cứ ai làm thiết kế được thì giúp em ,hoặc có thể giúp em thiết kế sơ đồ UML cũng được , em xin chân thành cảm ơn…

  7. LyLy said

    E có một bài tập như thế này thầy ah:
    yêu cầu login/logouut
    admin: manage user’s employee, manage user’s, assign user role, manage role
    manager: manage employee.
    thầy có bài demo nào tương tự ko ah?
    Nếu có thầy up lên giùm e nhé.
    E cảm ơn thầy ah.

  8. anh hải ơi anh có thể hướng dẫn em chi tiết quá trình làm một ví dụ đơn giản về cái mô hình MCV được không .Anh lên làm bằng video và có lời nói thì em dễ hiểu hơn.Anh gửi vào mail cho em đường link down ve nhe.Mail của em là nvloc.bkaedu@gmail.com thank anh nhiều

  9. Chickenmember said

    thầy ơi em gặp 1 vấn đề về JSF
    Em có 2 trang jsp ,1 trang thuần jsp la abc.jsp, 1 trang có chứa thần phần của jsf là bcd.jsp . khi em su dung <jsp:include page ="bcd.jsp" vào thì những thành phần trong không hiển thì mà chỉ hiển thị những thần phần ngoài ko hà. mong thầy trả lời sớm cám ơn thầy nhieu

  10. Võ Văn Hải said

    em thêm thuộc tính flush=”true” thử sao

  11. vuong nguyen said

    Chào anh !
    Nếu sử dụng hoàn toàn code java trong file jsp thì cũng chưa hoàn toàn tách biệt việc xử lí giữa controller và view. Em đang tìm hiểu về jstl , anh có thể demo lại phần view bằng jstl được ko.

  12. cảm ơn anh nhiều! Em mới tìm hiểu về mô hình MVC! đc đọc bài viết của anh em hiểu ra nhiều điều!
    Nếu có thể anh gửi cho em một số tài liệu về mô hình MVC nữa đc k?
    Mail của em là : giaothuy17@gmail.com
    ^^! Chúc Anh một buổi sáng tốt lanh! Have a nice day!

  13. TUẤN ANH said

    Thầy ơi!
    Khi em chạy các file .jsp nó báo lỗi như sau :
    HTTP Status 500 –

    ——————————————————————————–

    type Exception report

    message

    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    org.apache.jasper.JasperException: javax.servlet.ServletException: java.sql.SQLException: Access denied for user ”@’192.168.1.103′ (using password: NO)
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:500)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

    root cause

    javax.servlet.ServletException: java.sql.SQLException: Access denied for user ”@’192.168.1.103′ (using password: NO)
    org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:865)
    org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:794)
    org.apache.jsp.MyEShop_jsp._jspService(MyEShop_jsp.java:112)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:386)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

    root cause

    java.sql.SQLException: Access denied for user ”@’192.168.1.103′ (using password: NO)
    com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
    com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
    com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
    com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:910)
    com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3923)
    com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1273)
    com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2031)
    com.mysql.jdbc.ConnectionImpl.(ConnectionImpl.java:718)
    com.mysql.jdbc.JDBC4Connection.(JDBC4Connection.java:46)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    java.lang.reflect.Constructor.newInstance(Unknown Source)
    com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
    com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
    com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
    java.sql.DriverManager.getConnection(Unknown Source)
    java.sql.DriverManager.getConnection(Unknown Source)
    shopping.DBAction.(DBAction.java:18)
    org.apache.jsp.MyEShop_jsp._jspService(MyEShop_jsp.java:77)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:386)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

    note The full stack trace of the root cause is available in the Apache Tomcat/6.0.32 logs.

    —————————————————————–
    Thầy xem lại giúp em với

  14. Võ Văn Hải said

    Bạn xem lại kết nối đến SQL server. SQL instance trên máy bạn tên gì? username?password?,..

  15. TUẤN ANH said

    Vâng ạ ! em dùng mysql: username và password đều là :demo và em đã sửa lại các thông tin kết nối đến cơ sở dữ liệu rồi ạ.(trong file DBAction.java):như sau
    public DBAction() throws Exception {
    Class.forName(“com.mysql.jdbc.Driver”);
    con = DriverManager.getConnection(“jdbc:mysql://192.168.1.234:3306/demo”);

    …..
    }
    Em sửa như vậy mà khi chạy file .jsp lỗi vẫn như vậy. Thầy có thể nói em cách sửa không ạ !!

  16. TUẤN ANH said

    Thầy ơi ! Em làm được rồi ạ . Em cảm ơn thầy!!hix

  17. Thầy ơi cho em hỏi với ạ
    Cái đoạn mà tạo folder shopping cart em dùng Netbean IDE để làm WEB JSP em thấy nó hơi khác
    Thầy chỉ giúp em với ạ
    Em cảm ơn thầy

  18. Login Page

    function checkinput()
    {
    if(document.form1.username.value==””){
    alert(“Xin vui long nhap username”);
    document.form1.username.focus();
    return false;
    }
    if(document.form1.password.value==”” ){
    alert(“Xin vui long nhap password”);
    document.form1.password.focus();
    return false;
    }
    return true;
    }

    Administration Module

    Please enter username and password

    Username

    Password

     
     

    ==================================================
    Thầy xem hộ em đoạn CODE này với, nó chạy đến cái IF đầu tiên xong chạy ra ngoại lệ luôn
    nó bị làm sao hả thầy, thầy mail cho em sớm với nha
    em cảm ơn thầy

  19. Võ Văn Hải said

    Bạn dùng hàm getElelementByID thử xem.

  20. Cảnh said

    Cảm ơn Thầy, EM nghĩ có một bản dùng Mysql nữa thì càng hay.

  21. viet said

    thay lam giup em bai MVC Them sua xoa sinh vien voi

  22. Mina said

    Em chao Thay!

    em chay code cua Thay bi loi phia duoi!Loi do la gi vay That?

    org.apache.jasper.JasperException: Unable to compile class for JSP:

    An error occurred at line: 12 in the jsp file: /Checkout.jsp
    Giohang cannot be resolved to a type
    9:
    10: if(obj!=null){
    11:
    12: Giohang giohang=(Giohang)obj;
    13:
    14: ArrayListdssp=giohang.getGiohang();
    15:

    An error occurred at line: 12 in the jsp file: /Checkout.jsp
    Giohang cannot be resolved to a type
    9:
    10: if(obj!=null){
    11:
    12: Giohang giohang=(Giohang)obj;
    13:
    14: ArrayListdssp=giohang.getGiohang();
    15:

    An error occurred at line: 14 in the jsp file: /Checkout.jsp
    Monhang cannot be resolved to a type
    11:
    12: Giohang giohang=(Giohang)obj;
    13:
    14: ArrayListdssp=giohang.getGiohang();
    15:
    16: %>
    17:

    An error occurred at line: 38 in the jsp file: /Checkout.jsp
    Monhang cannot be resolved to a type
    35:
    36: <%int i=1;
    37:
    38: for(Monhang mh:dssp){
    39:
    40: String ms=mh.getSanpham().getMsSP();
    41:

  23. Võ Văn Hải said

    Là lỗi biên dịch đó em. Em phải xây dựng các đối tượng kia đã.

  24. nguyen vu said

    http://thungracinox.com.vn/Thungrac/DanhSachSanPham/46 khi em vao lần đầu tiên theo links này thì trang web thong báo lỗi. Nhưng reload lại thì lại ko bị lỗi. Anh xem cho em xem bị lỗi gì với ạ. Cảm ơn anh nhiều!

  25. hongdiep said

    Dạ cho em hỏi. Em chạy chương trình của thầy. Chường tình báo lỗi như sau:
    type Exception report

    message

    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    org.apache.jasper.JasperException: javax.servlet.ServletException: com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host has failed. java.net.ConnectException: Connection refused: connect
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:491)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:401)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    root cause

    javax.servlet.ServletException: com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host has failed. java.net.ConnectException: Connection refused: connect
    org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:862)
    org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:791)
    org.apache.jsp.MyEShop_jsp._jspService(MyEShop_jsp.java:114)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    root cause

    com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host has failed. java.net.ConnectException: Connection refused: connect
    com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
    com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(Unknown Source)
    com.microsoft.sqlserver.jdbc.SQLServerConnection.loginWithoutFailover(Unknown Source)
    com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(Unknown Source)
    com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(Unknown Source)
    java.sql.DriverManager.getConnection(DriverManager.java:582)
    java.sql.DriverManager.getConnection(DriverManager.java:207)
    shopping.DBAction.(DBAction.java:24)
    org.apache.jsp.MyEShop_jsp._jspService(MyEShop_jsp.java:78)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    note The full stack trace of the root cause is available in the Apache Tomcat/6.0.29 logs.

    Vậy là sao ạ? Mình phải sửa lỗi thế nào?
    Em chào thầy.

  26. nguyen tuyển said

    cái này bạn connect lỗi , k thấy host , có thế bạn dùng cả netbean nên bị trùng công 1080 . hãy thử check lại nhé . k biết mình nói có đúng k

  27. le tuyen said

    Xin chào thầy,
    Em đang xem về MVC, qua ví dụ của thầy em hiểu thêm nhiều vấn đề.
    Thầy có thể giúp em các tài liệu về MVC được không thầy?
    Chân thành cám ơn thầy

  28. Viết cái này cho vào Liferay dc ko hả thầy

  29. tèo bánh xèo said

    thầy ơi, e xài Mysql và e làm trên eclipse , khi e nhấn nút mua hàng thì lại báo lỗi The requested resource (/ShoppingCart/ControllerServlet) is not available

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

Join 2,195 other followers