ပုံမှန်ဆိုလျှင် ကျွှန်တော်တို့ကဲ့သို့ ဆားဗစ်ရှိပြီးသူတွေ အလုပ်ပြောင်းလျှင် ဘာတွေလုပ်ဘူးလဲ၊ ဘာတွေတက်လည်း၊ ရှေ့လျှောက်ဘာ ဆက်လုပ်ချင်တာလဲ အစရှိသည့်အရာများကို မေးလေ့ရှိပါသည်။ သူတို့ အလုပ်နှင့် ကိုက်လျှင် အလုပ်ဖြစ်သည်ကများပါသည်။
ရုတ်တရက် ဘွဲ့ရခါစ တစ်ယောက်လို စာမေးပွဲစစ်လာပါသည်။ ပုံလေးဆွဲ၊ စာလေးရေးနှင့် စာမျက်နှာ တစ်ဝက်စာပင် မရှိ။ ကျွှန်တော့်မှာ ရေးစရာကုန်သွားပါသည်။ ကျွှန်တော်အဲ့ဒီမှာ သိလိုက်ရပါသည်။ ငါဟာ MVC ကိုလည်း သုံးနေတယ်။ အမြဲလည်းကြားနေတယ်။ ကိုယ့်ဟာကိုယ် သိတယ်ပဲ ထင်နေခဲ့တယ်။ တကယ်တမ်းကျတော့ လုံးဝမသိပါလားလို့။ ကျွှန်တော် အဲ့ဒီအလုပ်စာမေးပွဲ မအောင်ခဲ့ပါ။
MVC Model
ယနေ့ ခေတ် MVC သည် Web Application များတွင် Design Pattern အနေဖြင့်၎င်း၊ အာကီတက်ချာ အနေနဲ့၎င်း၊ Framework အနေဖြင့်၎င်း လွန်စွာမှ လူပြောများ ခေတ်စားခဲ့သော အကြောင်းအရာတစ်ခု ဖြစ်၏။ ကျွှန်တော်ကိုယ်တိုင်လည်း အစက MVC သည် Web Application များ၏ အခြေခံဒီဇိုင်း တစ်ခုဟု ထင်နေခဲ့မိ၏။
သို့ရာတွင် MVC ၏ အစမှာ Desktop Application များမှ ဖြစ်ပါသည်။ ကနဦး Object Oriented ဘာသာရပ်တစ်ခု ဖြစ်သော Smalltalk ၏ Windows များစွာကို အသုံးပြုသော Desktop Application များအား ရေးသားရာတွင် စတင်စဉ်းစားခဲ့သော ဒီဇိုင်းတစ်မျိုး မှ စတင်ခဲ့ခြင်း ဖြစ်ပါသည်။ Application အတွင်း ပါဝင်သော Object များအား Model, View နှင့် Controller ဟု တာဝန်များခွဲကာ စဉ်းစားကြပါသည်။
Model
Model ဆိုသည်မှာ Windows ပေါ်တွင် ဖော်ပြပေးနေသော Object ကို ဆိုလိုပါသည်။ သို့ရာတွင် Model Object သည် မိမိသည် မည်သည့်နေရာတွင်ဖော်ပြ၍၊ မည်သည့်ပုံစံဖြင့် ဖော်ပြရမည်၊ မည်သည့် အရောင်ဖြင့် ဖော်ပြရမည် အစရှိသည့် အချက်အလက်များအား ပိုင်ဆိုင်ခြင်းမရှိပါ။ ပြောရမည်ဆိုလျှင် Business Data သက်သက်ကိုသာ ပြုပြင်ပြောင်းလည်းခြင်း၊ Reference လုပ်ခြင်းတို့သည်သာ Model Object ၏ တာဝန် ဖြစ်၏။
View
View Object သည် Model အား မည်သည့်နေရာတွင်၊ မည်သည့်ပုံစံဖြင့် ဖော်ပြရမည်ကို လုပ်ဆောင်ပေးနိုင်သော Object ဖြစ်၏။ အမည်အတိုင်း ဖော်ပြရန်သက်သက် တာဝန်ယူပေးပါသည်။ ဥပမာအားဖြင့် Model ၏ အချက်အလက်များအား၊ ဇယား အဖြစ်ဖော်ပြပေးမည်၊ Line Graph, Ball Graph, Circle Graph အစရှိသဖြင့် ဖော်ပြမည်၊ အစရှိသည်တို့ကို ပြုလုပ်ပေးရန် လိုအပ်ပါသည်။
စာမျက်နှာ အနည်းငယ်သာပါသော အပလီကေးရှင်းများဆိုပါက အချက်အလက်များအား စီမံခန့်ခွဲနိုင်သော Model နှင့် View ကို သာအသုံးပြုသော Pattern များနှင့်ပင် လုံလောက်ပါသည်။ Model View Pattern သည် အဆိုပါ Pattern မျိုးဖြစ်ပါသည်။
Controller
ဤသို့ဆိုလျှင် Controller သည် ဘာကြောင့်လိုအပ်သနည်း။ မည်သည့်တာဝန်ကို ထမ်းဆောင်ရမည်နည်း။ MVC ၏ အစပြုခဲ့ပုံကို ပြန်ကြည့်စေလိုပါသည်။ Data ပုံစံအမျိုးမျိုးနှင့်၊ Windows ပေါင်းများစွာကို အသုံးပြုသော အပလီကေးရှင်းအား ရေးသားရန် MVC ကို စတင်ခဲ့၏။ User ၏ ခိုင်းစေချက် အပေါ် မှုတည်၍ အချက်အလက် Model နှင့် View များအား အပြန်အလှန်ဆက်သွယ်ကာ သင့်တော်သလို ဆက်သွယ်ဖော်ပြ ပေးနိုင်ရန်သည် Controller ၏ တာဝန် တစ်ခု ဖြစ်လာပါသည်။
တနည်းဆိုရသော် Controller သည် Model နှင့် View အား စီမံခန့်ခွဲရန် အသုံးပြုသူ၏ အမိန့်ကို လက်ခံရယူပြီး၊ Model နှင့် View အား အပြန်အလှန် အမိန့်ပေးခိုင်းစေခြင်း အားဖြင့် အပလီကေးရှင်းတစ်ခုလုံးအား စီမံခန့်ခွဲပေးပါသည်။
ဤနည်းအားဖြင့် စတင်ခဲ့သော MVC သည် နောက်ပိုင်းတွင် J2EE ၏ Design Pattern တစ်ခု အဖြစ်အသုံးပြု လာရာမှ၊ Web Application အတော်များများ၏ အခြေခံ ဒီဇိုင်းတစ်ခု အဖြစ်၎င်း၊ Framework တစ်ခု အဖြစ်၎င်း J2EE ၏ MVC Pattern များကိုယ်တိုင်က အခြားသော Design Pattern များအား သုံးစွဲ၍ Softwar အာကီတက်ခြားအဖြစ်၎င်း တဖြည်းဖြည်း အသွင်ပြောင်း လာခဲ့ပါသည်။
ထို့ကြောင့် MVC အား ဤအချိန်တွင် တသမတ်တည်း အဓိပ္ပါယ်ဖွင့်ရန်မှာ လွန်စွာခက်ခဲပါလိမ့်မည်။ သို့ရာတွင် MVC သည် ရှုပ်ထွေးသော User Interface ကို အသုံးပြုသော အပလီကေးရှင်းများအား တည်ဆောက်ရာတွင် အထောက်အကူပြုရန် အသုံးပြုသင့်သော ဒီဇိုင်းတစ်ခုဟု သဘောပေါက်ပြီး၊ မိမိရေးသားလိုသော အပလီကေးရှင်း အပေါ်မှုတည်၍ အသုံးပြုသင့်သော Framework များအား ရွေးချယ် သွားနိုင်ပါလိမ့်မည်။
နမှုနာ အပလီကေးရှင်း
ကျွှန်တော်တို့ ပြီးခဲ့သော နမှုနာအပလီကေးရှင်းကို ပြန်ကြည့်ပါမည်။ Servlet သည် Request ၏ Path Info အားကြည့်ပြီး ဘယ် JSP ဖြင့် ဖော်ပြရမည်၊မည်သည့် လုပ်ဆောင်ချက်ဖြင့် အချက်အလက်များအား တွက်ချက် အသုံးပြုရမည်ဟု ခွဲခြားရေးသားခဲ့ပါသည်။
အချက်အလက်များအား ဖော်ပြပေးသော JSP များသည် View ဖြစ်၍၊ မည်သည့်အချက်အလက်ကို မည်သည့် View တွင် ဖော်ပြရမည်ဟု လုပ်ဆောင်ပေးနိုင်သော Servlet သည် Controller နှင့် Model ၏ နေရာတွင် တည်ရှိပြီး MVC ၏ ပုံစံတွင်ရှိသည်ဟု ဖော်ပြခဲ့၏။
အထက်ပါ နမှုနာတွင် တည်ဆောက်ပုံသည် Model နှင့် Controller အား မရှင်းမရှင်း ရေးသားထားသည်။ ထို့ကြောင့် ဘယ်အတိုင်းအတာအထိ Model က လုပ်သင့်သည်၊ Controller ကလုပ်သင့်သည် ဆိုသည်မှာ မကွဲပြားပေ။ အကယ်၍ ဤနမှုနာအတိုင်း စာမျက်နှာ လေးငါးခုသာရှိသော အပလိုဆိုလျှင် ကိစ္စမရှိ။
စာမျက်နှာ အများအပြားအား အသုံးပြုမည်၊ ထို့အပြင် Developer ပေါင်းများစွာဖြင့် ရေးသားရမည့် အပလီကေးရှင်းဆိုပါက ဤကဲ့သို့ရေးသားပုံမျိုးသည် လွန်စွာမှ အန္တရယ်ရှိပါသည်။ ပြုပြင်ရန် ခက်ခဲသလို၊ စာမျက်နှာတစ်ခု တိုးတိုင်း Controller အား ပြုပြင်ရမည် ဆိုလျှင် အတော်လေးကို ရှုပ်ထွေးသွားပါတော့မည်။ ထို့အတွက် ဤနေရာတွင် Model နှင့် Controller အား တိတိကျကျခွဲခြား တာဝန်ပေးထားရန် လိုအပ်ပါသည်။
Controller
ဤနမှုနာတွင် EM_Controller ကလပ်စ်သည် Controller ၏ နေရာအား ရယူထားပါသည်။ EM_Controller သည် HTTPServlet အား Extends လုပ်ထားသော ကလပ်စ်တစ်ခု ဖြစ်ပြီး၊ Request အပေါ်မှုတည်၍ သင့်တော်သော Model နှင့် View အား ခေါ်ယူကာ အလုပ်လုပ်စေရန် တာဝန် ယူထားရပါသည်။
EM_Controller#init သည် Servlet အား အင်းစတန့်စ် အဖြစ် မွေးဖွားစေရာတွင် ခေါ်ယူရမည့် လုပ်ဆောင်ချက်ဖြစ်ပြီး၊ အတွင်းပိုင်းတွင် အသုံးပြုလိုသား Properties ဖိုင်များနှင့် SQL များအား မံမိုရီပေါ်သို့ ခေါ်ယူပါသည်။ ဤနမှုနာတွင် MVC အပြင် Database ကိုလည်း ပြောင်းလည်း အသုံးပြုထားပါသည်။ ဤဘလောဂ်တွင် MVC အကြောင်းကို အဓိကထား ဖော်ပြလိုပါသဖြင့် SQL နှင့် ပတ်သက်သည်များကို နောက်ဘလောဂ်များဖြင့် ဖော်ပြသွားပါမည်။
EM_Controller.java
package com.mmju.jsp.ep6; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class EM_Controller extends HttpServlet { private static final long serialVersionUID = 1L; private Properties flowsProp; private Properties modelConf; public static Map<String, String> SQL_CONF = new HashMap<String, String>();; @Override public void init() throws ServletException { flowsProp = new Properties(); modelConf = new Properties(); final String _extension = ".sql"; BufferedReader br = null; try { // load flows flowsProp.load(getServletContext().getResourceAsStream( "/WEB-INF/conf/apl/flows.properties")); // load models modelConf.load(getServletContext().getResourceAsStream( "/WEB-INF/conf/apl/model.properties")); // load sql File sqlPath = new File(getServletContext().getRealPath( "/WEB-INF/conf/sql")); File[] sqlFiles = sqlPath.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(_extension); } }); for (int i = 0; i < sqlFiles.length; i++) { String name = sqlFiles[i].getName().replace(_extension, ""); StringBuilder sb = new StringBuilder(); br = new BufferedReader(new InputStreamReader( new FileInputStream(sqlFiles[i]))); String line = null; while (null != (line = br.readLine())) { sb.append(line); } EM_SqlConf.put(name, sb.toString()); } } catch (Exception e) { throw new RuntimeException(); } finally { if (null != br) { try { br.close(); } catch (IOException e) { } } } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @SuppressWarnings("unchecked") @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // set param ref_key String businessID = this.getBusinessID(req.getRequestURI()); req.setAttribute("ref_key", businessID); // getModel List<EM_Model> models = this.getModels(businessID); for (EM_Model model : models) { // model#setInput model.setInputs(req.getParameterMap()); // model#doBusiness model.doBusiness(); } // set View this.setView(models, req, resp); } /** * To get Model Classes setting in model configuration * * @param businessIDs * @return */ private List<EM_Model> getModels(String businessID) { try { List<EM_Model> models = new ArrayList<EM_Model>(); String names = (String) this.modelConf.get(businessID); if (null != names) { String[] classNames = names.split(","); if (null != classNames) { for (String name : classNames) { System.out.println(name); EM_Model model = (EM_Model) Class.forName(name.trim()) .newInstance(); if (null != model) models.add(model); } } } return models; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); } } /** * setting view * <ul> * <li>getting output from business logic model</li> * <li>set the result to HttpRequest</li> * <li>despatch request to view</li> * </ul> * * @param outputs * @param req * @param resp * @throws ServletException * @throws IOException */ private void setView(List<EM_Model> models, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { for (int i = 0; i < models.size(); i++) { // Outputs Map<String, Object> outputs = models.get(i).getOutPuts(); Iterator<String> itr = outputs.keySet().iterator(); // Set Outputs while (itr.hasNext()) { String key = itr.next(); req.setAttribute(key, outputs.get(key)); } } this.getDispatcher(req.getRequestURI()).forward(req, resp); } /** * getting business logic id * * @param reqPathInf * @return */ private String getBusinessID(String reqPathInf) { if (null != reqPathInf && !reqPathInf.isEmpty()) { String[] infos = reqPathInf.split("/"); for (int i = 0; i < infos.length; i++) { if (infos.length - 1 == i) { return infos[i].replace(".em", ""); } } } return null; } /** * getDispatcher * * @param reqInfo * @return */ private RequestDispatcher getDispatcher(String reqInfo) { if (null != reqInfo && !reqInfo.isEmpty()) { String[] infos = reqInfo.split("/"); StringBuilder sb = new StringBuilder("/jsp"); for (int i = 0; i < infos.length; i++) { if (infos[i].length() > 0) { sb.append("/"); if (infos.length - 1 == i) { String key = infos[i].replace(".em", ""); sb.append(flowsProp.getProperty(key)); } else { sb.append(infos[i]); } } } return getServletContext().getRequestDispatcher(sb.toString()); } return null; } }
ပြီးပါက စာကြောင်း ၉၈ဖြင့် အသုံးပြုမည့် Model အား ရယူပါသည်။ Business ID များတွင် Model များအား အသုံးပြုသည့်အခါလည်း ရှိမည်၊ အသုံးမပြုပဲ Flow ကို သာအသုံးပြုလိုသည့်အခါမျိုးလည်း ရှိပါမည်။ ဤဥပမာတွင် edit, confirm နှင့် details အစရှိသည့် Business ID များသည်၊ Model များအား အသုံးပြုရန်မလိုပေ။ လက်ရှိ အချက်အလက်များအား အခြားသော View ဖြင့် ပြောင်းလည်း ဖော်ပြရုံသာ ဖြစ်သည်။ ထိုအခါမျိုးတွင် flow.properties တွင်သာ ဖော်ပြလိုသည့် View အားရေးသားပြီး၊ model.properties တွင် အထွေအထူး ရေးသားရန် မလိုအပ်ပါ။
တဖန် add, delete နှင့် update တို့သည်လည်း လုပ်ဆောင်ချက်များ အပြီးတွင် ကားလစ်အား ရယူရန် လိုအပ်ပါသည်။ ထို့ကြောင့် Model နှစ်ခုအား တစ်ပြိုင်နက်တည်း အသုံးပြုရန် လိုအပ်ပါသည်။ ထိုအခါမျိုးတွင် add တွင် add နှင့် select လုပ်မည့် model အား ကော်မာခြားပြီး ရေးသားရန် လိုအပ်ပါသည်။ ထိုအခါမျိုးတွင် add လုပ်ပြီး select လုပ်ကာ ရလဒ်အား flow တွင် သတ်မှတ်ထားသော JSP ဖြင့် ဖော်ပြမည် ဖြစ်ပါသည်။
model.properties
list=com.mmju.jsp.ep6.model.Md_select update=com.mmju.jsp.ep6.model.Md_Update,com.mmju.jsp.ep6.model.Md_select delete=com.mmju.jsp.ep6.model.Md_Delete,com.mmju.jsp.ep6.model.Md_select add=com.mmju.jsp.ep6.model.Md_add,com.mmju.jsp.ep6.model.Md_selectစာကြောင်း ၁၀၀ တွင် ရရှိထားသော Model များအား for ဝါကျကို အသုံးပြုကာ တစ်ခုဆီ၊ စာကြောင်း ၁၀၂ ဖြင့် Input Data များအား ပေးကမ်းကာ၊ EM_Model#doBusiness ဖြင့် သက်ဆိုင်ရာ လုပ်ငန်းဆောင်တာများ အား လုပ်ဆောင်စေပါသည်။ နောက်ဆုံးတွင် စာကြောင်း ၁၀၈ ဖြင့် setView လုပ်ဆောင်ချက်အား ခေါ်ယူကာ Model ၏ ရလဒ်အား Request အတွင်းသို့ ဖြည့်စွက်ကာ flow.properties တွင် သတ်မှတ်ထားသော JSP အား forward လုပ်လိုက်ခြင်းသာဖြစ်၏။
Model
ဤနမှုနာထဲတွင် Model များအား အုပ်စုတစ်ခု အနေဖြင့် အသုံးပြုနိုင်ရန် EM_Model ဟု Abstract Class တစ်ခု အားပြင်ဆင်ထားပါသည်။ ထိုအထဲတွင် Model အဖြစ် မရှိမဖြစ်လိုအပ်သည့် လုပ်ဆောင်ချက်များ၊ နှင့် အချက်အလက်များအား သက်မှတ် ရေးသားထားပါသည်။ Model အလိုက် ပြောင်းရေးရန် လိုအပ်သည့် လုပ်ဆောင်ချက်ကိုသာ abstract လုပ်ဆောင်ချက်အဖြစ် ရေးသားထားပြီး၊ အမွေဆက်ခံသည့် Sub Class သည် အထက်ပါ လုပ်ဆောင်ချက်ကို မဖြစ်မနေ ဖြည့်စွက် ရေးသားရန် လိုအပ်ပါသည်။
EM_Model.java
package com.mmju.jsp.ep6; import java.sql.Connection; import java.util.HashMap; import java.util.Map; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; public abstract class EM_Model { protected Map<String, Object> inPuts; protected Map<String, Object> outPuts; public EM_Model(){ outPuts = new HashMap<String, Object>(); } public void setInputs(Map<String, Object> input) { this.inPuts = input; } public Map<String, Object> getOutPuts() { return this.outPuts; } /** * Main Business Logic */ public abstract void doBusiness(); /** * getConnection * * @return JDBC Connection */ protected Connection getConnection() { try { Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/ezjsp"); return ds.getConnection(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); } } protected void setOutputs(String key, Object value) { outPuts.put(key, value); } protected Map<String, Object> getInputs() { return this.inPuts; } protected String getStringValue(String key) { Object value = this.inPuts.get(key); if(null != value && value instanceof String []) { String [] params = (String [])value; if(params.length > 0) return params[0]; } return null; } }
ဤနမှုနာထဲတွင် အထက်ပါ EM_Modelအား Extends လုပ်ပြီး Model အဖြစ်အသုံးပြုလိုသည့် ကလပ်စ် များမှာ အောက်ပါအတိုင်းဖြစ်ပါသည်။
- com.mmju.jsp.ep6.model.Md_add.java
- com.mmju.jsp.ep6.model.Md_Delete.java
- com.mmju.jsp.ep6.model.Md_select.java
- com.mmju.jsp.ep6.model.Md_Update.java
Md_add.java
package com.mmju.jsp.ep6.model; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import com.mmju.jsp.ep6.EM_Model; import com.mmju.jsp.ep6.EM_SqlConf; public class Md_add extends EM_Model { @Override public void doBusiness() { Connection conn = null; // build sql try { conn = getConnection(); PreparedStatement pst = conn.prepareStatement(EM_SqlConf .getSql("Md_add_SQLI_001")); pst.setString(1, getStringValue("brand")); pst.setString(2, getStringValue("model")); pst.setString(3, getStringValue("year")); if(pst.executeUpdate() < 0) { throw new RuntimeException("Fail to insert Query."); } } catch (SQLException e) { throw new RuntimeException(e.getMessage()); } finally { if(null != conn) { try { conn.close(); } catch (SQLException e) { } } } } }Md_add သည် Car အချက်အလက်များအား အသစ် ဖြည့်စွက်ရန် တာဝန်ကျသော Data Model ကလပ်စ် ဖြစ်ပါသည်။ EM_Model ကလပ်စ်အား Extends လုပ်ထားပြီး၊ doBusiness လုပ်ဆောင်ချက်အား Override လုပ်ထားပါသည်။ Controller မှ ခေါ်ယူသည့် အခါတွင် အလုပ်လုပ်မည့် လုပ်ဆောင်ချက်ဖြစ်သည်။
အတွင်းပိုင်းတွင် Super Class ၏ getConnection ဖြင့် Database Connection Object အား ခေါ်ယူကာ၊ PrepareStatement အော့ဘဂျက်အား ပြင်ဆင်ပါသည်။ EM_SqlConf သည် Sql ဖိုင်များအား ID ဖြင့် တွဲကာ Framework အတွင်းတွင် သိမ်းဆည်းထားသော Static Class တစ်ခုဖြစ်ပါသည်။ MVC အကြောင်းကို အဓိက ဖော်ပြလိုပါသဖြင့် ဤနေရာတွင် အသေးစိတ် မရှင်းတော့ပါ။
တဖန် စာကြောင်း ၂၂မှ ၂၄အထိ Request Parameter များအား ရယူကာအသီးသီး PrepareStatement Object တွင် ဖြည့်စွက်ရေးသားပါသည်။ ပြီးပါက စာကြောင်း ၂၆ဖြင့် executeUpdate လုပ်ဆောင်ချက်ဖြင့် Database အား Update လုပ်ပါသည်။ ဤနည်းအားဖြင့် အသီးသီး အချက်အလက်များအား ဖြည့်စွက်ခြင်း၊ပြုပြင်ခြင်း၊ ဖျက်စီးပစ်ခြင်းနှင့် ရှာဖွေခြင်းတို့ကို လုပ်ဆောင်စေပါသည်။
ဤနည်းအားဖြင့် Model များမှ လုပ်ဆောင်ထားသော ရလဒ်များအား Controller မှတဆင့် getOutputs ဖြင့် ရယူကာ သက်ဆိုင်ရာ View ဆီသို့ ပေးပို့၍ ပုံဖော်နေခြင်း ဖြစ်ပါသည်။ View နှင့် ပတ်သက်သည့် အကြောင်းအရာများမှာ ပြီးခဲ့သော အခန်းမှ များစွာပြောင်းလည်းခြင်း မရှိပါသဖြင့် အသေးစိတ်မဖော်ပြတော့ပါ။
JSP နှင့် သိပ်ပြီး မပတ်သက်သောကြောင့် အများကြီးကျော်၍ ရေးသားသွားပါသည်။ အကယ်၍ နားမလည်သည့်နေရာများ ရှိခဲ့ပါက ဘလောဂ်မှတဆင့်သော်၎င်း၊ Facebook မှ တဆင့်သော်၎င်း မေးမြန်းနိုင်ပါသည်။
Project Source
https://github.com/minlwin/mmju/tree/master/jsp-tutorials
နမှုနာ စမ်းသပ်ရန်
http://jsp-tutorials.minlwin.cloudbees.net/
ဆက်ပါဦးမည်။လေးစားစွာဖြင့်။
မင်းလွင်
No comments:
Post a Comment