版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Day1一、使用JavaEE版的Eclipse開發(fā)動態(tài)的WEB工程(JavaWEB項目)1).把開發(fā)選項切換到JavaEE2).可以在Window->ShowView中找到PackageExplorer,并把其拖拽到開發(fā)區(qū)的左邊3).在Servers面板中新建Tomcat服務(wù)器.一定要關(guān)聯(lián)到Tomcat安裝的根目錄4).新建一個DynamicWebProject.其中TargetRuntime需選擇Tomcat6.05).開發(fā)JavaWEB應(yīng)用6).可以通過runonserver來運(yùn)行WEB項目.二、Servlet的HelloWorld1).創(chuàng)建一個Servlet接口的實現(xiàn)類.publicclassHelloServletimplementsServlet2).在web.xml文件中配置和映射這個Servlet(因此可以通過瀏覽器訪問java類) <!--配置和映射Servlet--> <servlet> <!--Servlet注冊的名字--> <servlet-name>helloServlet</servlet-name> <!--Servlet的全類名--> <servlet-class>com.atguigu.javaweb.HelloServlet</servlet-class>指向HelloServlet文件 </servlet> <servlet-mapping> <!--需要和某一個servlet標(biāo)簽的serlvet-name子標(biāo)簽的文本節(jié)點一致--> <servlet-name>helloServlet</servlet-name> <!--映射具體的訪問路徑:/代表當(dāng)前WEB應(yīng)用的根目錄.--> <url-pattern>/hello</url-pattern> </servlet-mapping>三、Servlet容器:運(yùn)行Servlet、JSP、Filter等的軟件環(huán)境.1).可以來創(chuàng)建Servlet,并調(diào)用Servlet的相關(guān)生命周期方法.2).JSP,Filter,Listener,Tag...四、Servlet生命周期的方法:以下方法都是由Serlvet容器負(fù)責(zé)調(diào)用.1).構(gòu)造器:只被調(diào)用一次.只有第一次請求Servlet時,創(chuàng)建Servlet的實例.調(diào)用構(gòu)造器.這說明Serlvet的單實例的!2).init方法:只被調(diào)用一次.在創(chuàng)建好實例后立即被調(diào)用.用于初始化當(dāng)前Servlet.3).service:被多次調(diào)用.每次請求都會調(diào)用service方法.實際用于響應(yīng)請求的.4).destroy:只被調(diào)用一次.在當(dāng)前Servlet所在的WEB應(yīng)用被卸載前調(diào)用.用于釋放當(dāng)前Servlet所占用的資源.五、load-on-startup參數(shù):1).配置在servlet節(jié)點中: <servlet> <!--Servlet注冊的名字--> <servlet-name>secondServlet</servlet-name> <!--Servlet的全類名--> <servlet-class>com.atguigu.javaweb.SecondServlet</servlet-class> <!--可以指定Servlet被創(chuàng)建的時機(jī)--> <load-on-startup>2</load-on-startup> </servlet> 2).load-on-startup:可以指定Serlvet被創(chuàng)建的時機(jī).若為負(fù)數(shù),則在第一次請求時被創(chuàng)建.若為0或正數(shù),則在當(dāng)前WEB應(yīng)用被Serlvet容器加載時創(chuàng)建實例,且數(shù)組越小越早被創(chuàng)建.六、關(guān)于serlvet-mapping:1).同一個Servlet可以被映射到多個URL上,即多個<servlet-mapping>元素的<servlet-name>子元素的設(shè)置值可以是同一個Servlet的注冊名。2).在Servlet映射到的URL中也可以使用*通配符,但是只能有兩種固定的格式:一種格式是“*.擴(kuò)展名”,另一種格式是以正斜杠(/)開頭并以“/*”結(jié)尾。<servlet-mapping> <servlet-name>secondServlet</servlet-name> <url-pattern>/*</url-pattern>/*表示所有類型可匹配</servlet-mapping>OR<servlet-mapping> <servlet-name>secondServlet</servlet-name> <url-pattern>*.html</url-pattern>*.html匹配.html</servlet-mapping>注意:以下的既帶/又帶擴(kuò)展名的不合法.<servlet-mapping> <servlet-name>secondServlet</servlet-name> <url-pattern>/*.action</url-pattern></servlet-mapping>七、ServletConfig:封裝了Serlvet的配置信息,并且可以獲取ServletContext對象1).配置Serlvet的初始化參數(shù) <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.atguigu.javaweb.HelloServlet</servlet-class> <!--配置Serlvet的初始化參數(shù)。且節(jié)點必須在load-on-startup節(jié)點的前面--> <init-param> <!--參數(shù)名--> <param-name>user</param-name> <!--參數(shù)值--> <param-value>root</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>1230</param-value> </init-param> <load-on-startup>-1</load-on-startup> </servlet>2).獲取初始化參數(shù): >getInitParameter(Stringname):獲取指定參數(shù)名的初始化參數(shù)>getInitParameterNames():獲取參數(shù)名組成的Enumeration對象.Stringuser=servletConfig.getInitParameter("user"); System.out.println("user:"+user); Enumeration<String>names=servletConfig.getInitParameterNames(); while(names.hasMoreElements()){ Stringname=names.nextElement(); Stringvalue=servletConfig.getInitParameter(name); System.out.println("^^"+name+":"+value); }3).獲取Serlvet的配置名稱(了解)八、ServletContext1).可以由SerlvetConfig獲取:ServletContextservletContext=servletConfig.getServletContext();2).該對象代表當(dāng)前WEB應(yīng)用:可以認(rèn)為SerlvetContext是當(dāng)前WEB應(yīng)用的一個大管家.可以從中獲取到當(dāng)前WEB應(yīng)用的各個方面的信息.①.獲取當(dāng)前WEB應(yīng)用的初始化參數(shù)設(shè)置初始化參數(shù):可以為所有的Servlet所獲取,而Servlet的初始化參數(shù)只用那個Serlvet可以獲取.<!--配置當(dāng)前WEB應(yīng)用的初始化參數(shù)--><context-param> <param-name>driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value></context-param>方法:getInitParametergetInitParameterNames 代碼:ServletContextservletContext=servletConfig.getServletContext(); Stringdriver=servletContext.getInitParameter("driver");System.out.println("driver:"+driver);Enumeration<String>names2=servletContext.getInitParameterNames();while(names2.hasMoreElements()){ Stringname=names2.nextElement(); System.out.println("-->"+name);}②.獲取當(dāng)前WEB應(yīng)用的某一個文件在服務(wù)器上的絕對路徑,而不是部署前的路徑getRealPath(Stringpath);代碼:StringrealPath=servletContext.getRealPath("/note.txt");System.out.println(realPath);③.獲取當(dāng)前WEB應(yīng)用的名稱:getContextPath()代碼:StringcontextPath=servletContext.getContextPath();System.out.println(contextPath);④.獲取當(dāng)前WEB應(yīng)用的某一個文件對應(yīng)的輸入流.getResourceAsStream(Stringpath):path的/為當(dāng)前WEB應(yīng)用的根目錄.代碼:InputStreamis2=servletContext.getResourceAsStream("/WEB-INF/classes/perties"); ⑤.和attribute相關(guān)的幾個方法: 九、GET請求和POST請求:1).使用GET方式傳遞參數(shù):①.在瀏覽器地址欄中輸入某個URL地址或單擊網(wǎng)頁上的一個超鏈接時,瀏覽器發(fā)出的HTTP請求消息的請求方式為GET。②.如果網(wǎng)頁中的<form>表單元素的method屬性被設(shè)置為了“GET”,瀏覽器提交這個FORM表單時生成的HTTP請求消息的請求方式也為GET。③.使用GET請求方式給WEB服務(wù)器傳遞參數(shù)的格式:/counter.jsp?name=lc&password=123④.使用GET方式傳送的數(shù)據(jù)量一般限制在1KB以下。2).使用POST方式傳遞參數(shù):①.POST請求方式主要用于向WEB服務(wù)器端程序提交FORM表單中的數(shù)據(jù):form表單的method置為POST②.POST方式將各個表單字段元素及其數(shù)據(jù)作為HTTP消息的實體內(nèi)容發(fā)送給WEB服務(wù)器,傳送的數(shù)據(jù)量要比使用GET方式傳送的數(shù)據(jù)量大得多。POST/counter.jspHTTP/1.1referer:http://localhost:8080/Register.htmlcontent-type:application/x-www-form-urlencodedhost:localhost:8080content-length:43name=zhangsan&password=123--請求體中傳遞參數(shù).十、如何在Serlvet中獲取請求信息:1).Servlet的service()方法用于應(yīng)答請求:因為每次請求都會調(diào)用service()方法publicvoidservice(ServletRequestrequest,ServletResponseresponse) throwsServletException,IOException ServletRequest:封裝了請求信息.可以從中獲取到任何的請求信息.ServletResponse:封裝了響應(yīng)信息,如果想給用戶什么響應(yīng),具體可以使用該接口的方法實現(xiàn).這兩個接口的實現(xiàn)類都是服務(wù)器給予實現(xiàn)的,并在服務(wù)器調(diào)用service方法時傳入.2).ServletRequest:封裝了請求信息.可以從中獲取到任何的請求信息.①.獲取請求參數(shù): >StringgetParameter(Stringname):根據(jù)請求參數(shù)的名字,返回參數(shù)值. 若請求參數(shù)有多個值(例如checkbox),該方法只能獲取到第一個提交的值. >String[]getParameterValues(Stringname):根據(jù)請求參數(shù)的名字,返回請求參數(shù)對應(yīng)的字符串?dāng)?shù)組. >EnumerationgetParameterNames():返回參數(shù)名對應(yīng)的Enumeration對象, 類似于ServletConfig(或ServletContext)的getInitParameterNames()方法. >MapgetParameterMap():返回請求參數(shù)的鍵值對:key:參數(shù)名,value:參數(shù)值,String數(shù)組類型.②.獲取請求的URI: HttpServletRequesthttpServletRequest=(HttpServletRequest)request; StringrequestURI=httpServletRequest.getRequestURI(); System.out.println(requestURI);///day_29/loginServlet③.獲取請求方式: Stringmethod=httpServletRequest.getMethod(); System.out.println(method);//GET ④.若是一個GET請求,獲取請求參數(shù)對應(yīng)的那個字符串,即?后的那個字符串. StringqueryString=httpServletRequest.getQueryString(); System.out.println(queryString);//user=atguigu&password=123456&interesting=game&interesting=party&interesting=shopping⑤.獲取請求的Serlvet的映射路徑StringservletPath=httpServletRequest.getServletPath();System.out.println(servletPath);///loginServlet⑥.和attribute相關(guān)的幾個方法: 3).HttpServletRequest:是SerlvetRequest的子接口.針對于HTTP請求所定義.里邊包含了大量獲取HTTP請求相關(guān)的方法.4).ServletResponse:封裝了響應(yīng)信息,如果想給用戶什么響應(yīng),具體可以使用該接口的方法實現(xiàn).①.*getWriter():返回PrintWriter對象.調(diào)用該對象的print()方法,將把print()中的參數(shù)直接打印到客戶的瀏覽器上.②.設(shè)置響應(yīng)的內(nèi)容類型:response.setContentType("application/msword");③.voidsendRedirect(Stringlocation):請求的重定向.(此方法為HttpServletResponse中定義.)在web.xml文件中設(shè)置兩個WEB應(yīng)用的初始化參數(shù),user,password.定義一個login.html,里邊定義兩個請求字段:user,password.發(fā)送請求到loginServlet在創(chuàng)建一個LoginServlet,在其中獲取請求的user,password.比對其和web.xml文件中定義的請求參數(shù)是否一致若一致,響應(yīng)Hello:xxx,若不一致,響應(yīng)Sorry:xxxxxx為user.補(bǔ)充:http://localhost:8080/day0001/app/index.jspgetContextPath()/day0001getServletPath()/app/index.jspgetRequestUri()/day0001/app/index.jspDay2一、GenericServlet(了解):1).是一個Serlvet.是Servlet接口和ServletConfig接口的實現(xiàn)類.但是一個抽象類.其中的service方法為抽象方法2).如果新建的Servlet程序直接繼承GenericSerlvet會使開發(fā)更簡潔.3).具體實現(xiàn):①.在GenericServlet中聲明了一個SerlvetConfig類型的成員變量,在init(ServletConfig)方法中對其進(jìn)行了初始化②.利用servletConfig成員變量的方法實現(xiàn)了ServletConfig接口的方法③.還定義了一個init()方法,在init(SerlvetConfig)方法中對其進(jìn)行調(diào)用,子類可以直接覆蓋init()在其中實現(xiàn)對Servlet的初始化.④.不建議直接覆蓋init(ServletConfig),因為如果忘記編寫super.init(config);而還是用了SerlvetConfig接口的方法,則會出現(xiàn)空指針異常.⑤.新建的init(){}并非Serlvet的生命周期方法.而init(ServletConfig)是生命周期相關(guān)的方法.publicabstractclassGenericServletimplementsServlet,ServletConfig{ /**以下方法為Servlet接口的方法**/ @Override publicvoiddestroy(){} @Override publicServletConfiggetServletConfig(){ returnservletConfig; } @Override publicStringgetServletInfo(){ returnnull; } privateServletConfigservletConfig; @Override publicvoidinit(ServletConfigarg0)throwsServletException{ this.servletConfig=arg0; init(); } publicvoidinit()throwsServletException{} @Override publicabstractvoidservice(ServletRequestarg0,ServletResponsearg1) throwsServletException,IOException; /**以下方法為ServletConfig接口的方法**/ @Override publicStringgetInitParameter(Stringarg0){ returnservletConfig.getInitParameter(arg0); } @Override publicEnumerationgetInitParameterNames(){ returnservletConfig.getInitParameterNames(); } @Override publicServletContextgetServletContext(){ returnservletConfig.getServletContext(); } @Override publicStringgetServletName(){ returnservletConfig.getServletName(); }}二、HttpServlet:1).是一個Servlet,繼承自GenericServlet.針對于HTTP協(xié)議所定制.2).在service()方法中直接把ServletReuqest和ServletResponse轉(zhuǎn)為HttpServletRequest和HttpServletResponse.并調(diào)用了重載的service(HttpServletRequest,HttpServletResponse)在service(HttpServletRequest,HttpServletResponse)獲取了請求方式:request.getMethod().根據(jù)請求方式有創(chuàng)建了doXxx()方法(xxx為具體的請求方式,比如doGet,doPost)@Overridepublicvoidservice(ServletRequestreq,ServletResponseres)throwsServletException,IOException{HttpServletRequestrequest;HttpServletResponseresponse;try{request=(HttpServletRequest)req;response=(HttpServletResponse)res;}catch(ClassCastExceptione){thrownewServletException("non-HTTPrequestorresponse");}service(request,response);}publicvoidservice(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ //1.獲取請求方式. Stringmethod=request.getMethod(); //2.根據(jù)請求方式再調(diào)用對應(yīng)的處理方法 if("GET".equalsIgnoreCase(method)){ doGet(request,response); }elseif("POST".equalsIgnoreCase(method)){ doPost(request,response); }}publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ //TODOAuto-generatedmethodstub }publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ //TODOAuto-generatedmethodstub }3).實際開發(fā)中,直接繼承HttpServlet,并根據(jù)請求方式復(fù)寫doXxx()方法即可.4).好處:直接由針對性的覆蓋doXxx()方法;直接使用HttpServletRequest和HttpServletResponse,不再需要強(qiáng)轉(zhuǎn).三、轉(zhuǎn)發(fā)://1、調(diào)用HttpServletRequest的getRequestDispatcher()方法,參數(shù)為轉(zhuǎn)發(fā)地址,獲取DequestDispatcher對象 Stringpath="testServlet"; RequestDispatcherrequestDispatcher=request.getRequestDispatcher("/"+path); //2、調(diào)用HttpServletRequest的forward(request,response)進(jìn)行轉(zhuǎn)發(fā) requestDispatcher.forward(request,response); 重定向//直接調(diào)用response.sendRedirect()方法,參數(shù)為重定向的地址 response.sendRedirect("testServlet");在MySQL數(shù)據(jù)庫中創(chuàng)建一個test_users數(shù)據(jù)表,添加3個字段:id,user,password.并錄入幾條記錄.定義一個login.html,里邊定義兩個請求字段:user,password.發(fā)送請求到loginServlet在創(chuàng)建一個LoginServlet(需要繼承自HttpServlet,并重寫其doPost方法),在其中獲取請求的user,password.利用JDBC從test_users中查詢有沒有和頁面輸入的user,password對應(yīng)的記錄SELECTcount(id)FROMtest_usersWHEREuser=?ANDpassword=?count(id)大于0,登陸成功,等于0,登錄失敗若有,響應(yīng)Hello:xxx,若沒有,響應(yīng)Sorry:xxxxxx為user.四、請求的轉(zhuǎn)發(fā)和重定向:1).本質(zhì)區(qū)別:請求的轉(zhuǎn)發(fā)只發(fā)出了一次請求,而重定向則發(fā)出了兩次請求.具體:①.請求的轉(zhuǎn)發(fā):地址欄是初次發(fā)出請求的地址.請求的重定向:地址欄不再是初次發(fā)出的請求地址.地址欄為最后響應(yīng)的那個地址②.請求轉(zhuǎn)發(fā):在最終的Servlet中,request對象和中轉(zhuǎn)的那個request是同一個對象.請求的重定向:在最終的Servlet中,request對象和中轉(zhuǎn)的那個request不是同一個對象.③.請求的轉(zhuǎn)發(fā):只能轉(zhuǎn)發(fā)給當(dāng)前WEB應(yīng)用的的資源請求的重定向:可以重定向到任何資源.④.請求的轉(zhuǎn)發(fā):/代表的是當(dāng)前WEB應(yīng)用的根目錄,如/c.jsp請求的重定向:/代表的是當(dāng)前WEB站點的根目錄,如/day30/c.jsp注:當(dāng)前WEB應(yīng)用的根目錄:http://localhost:8080/day30/當(dāng)前站點的根目錄:http://localhost:8080/五、JSP:1).WHY:JSP是簡Servlet編寫的一種技術(shù),它將Java代碼和HTML語句混合在同一個文件中編寫,只對網(wǎng)頁中的要動態(tài)產(chǎn)生的內(nèi)容采用Java代碼來編寫,而對固定不變的靜態(tài)內(nèi)容采用普通靜態(tài)HTML頁面的方式編寫。2).JavaServerPage:Java服務(wù)器端網(wǎng)頁.在HTML頁面中編寫Java代碼的頁面.2).helloworld:新建一個JSP頁面,在body節(jié)點內(nèi)的<%%>即可編寫Java代碼.<body> <% Datedate=newDate(); System.out.print(date); %></body>3).JSP可以放置在WEB應(yīng)用程序中的除了WEB-INF及其子目錄外的其他任何目錄中,JSP頁面的訪問路徑與普通HTML頁面的訪問路徑形式也完全一樣。4).JSP的運(yùn)行原理:JSP本質(zhì)上是一個Servlet.每個JSP頁面在第一次被訪問時,JSP引擎將它翻譯成一個Servlet源程序,接著再把這個Servlet源程序編譯成Servlet的class類文件.然后再由WEB容器(Servlet引擎)像調(diào)用普通Servlet程序一樣的方式來裝載和解釋執(zhí)行這個由JSP頁面翻譯成的Servlet程序。5).JSP頁面的隱含變量:沒有聲明就可以使用的對象.JSP頁面一共有9個隱含對象.publicvoid_jspService(HttpServletRequestrequest,HttpServletResponseresponse)throwsjava.io.IOException,ServletException{PageContextpageContext=null;HttpSessionsession=null;ServletContextapplication=null;ServletConfigconfig=null;JspWriterout=null;Objectpage=this; //... //使用<%%>編寫的代碼在此位置.可以用到request,response,pageContext,session //application,config,out,page這8個隱含對象.(實際上還可以使用一個叫exception的隱含對象)}①.request:HttpServletRequest的一個對象.*②.response:HttpServletResponse的一個對象(在JSP頁面中幾乎不會調(diào)用response的任何方法.)③.pageContext:頁面的上下文,是PageContext的一個對象.可以從該對象中獲取到其他8個隱含對象.也可以從中獲取到當(dāng)前頁面的其他信息.(學(xué)習(xí)自定義標(biāo)簽時使用它)*④.session:代表瀏覽器和服務(wù)器的一次會話,是HttpSession的一個對象.后面詳細(xì)學(xué)習(xí).*⑤.application:代表當(dāng)前WEB應(yīng)用.是ServletContext對象.*⑥.config:當(dāng)前JSP對應(yīng)的Servlet的ServletConfig對象(幾乎不使用).若需要訪問當(dāng)前JSP配置的初始化參數(shù),需要通過映射的地址才可以.映射JSP:<servlet> <servlet-name>hellojsp</servlet-name> <jsp-file>/hello.jsp</jsp-file> <init-param> <param-name>test</param-name> <param-value>testValue</param-value> </init-param></servlet><servlet-mapping> <servlet-name>hellojsp</servlet-name> <url-pattern>/hellojsp</url-pattern> </servlet-mapping>⑦.out:JspWriter對象.調(diào)用out.println()可以直接把字符串打印到瀏覽器上.*⑧.page:指向當(dāng)前JSP對應(yīng)的Servlet對象的引用,但為Object類型,只能調(diào)用Object類的方法(幾乎不使用)⑨.exception:在聲明了page指令的isErrorPage="true"時,才可以使用.*<%@pageisErrorPage="true"%>pageContext,request,session,application(對屬性的作用域的范圍從小到大)out,response,config,pageexception6).JSP模版元素:JSP頁面中的靜態(tài)HTML內(nèi)容稱7).JSP表達(dá)式(expression)提供了將一個java變量或表達(dá)式的計算結(jié)果輸出到客戶端的簡化方式,它將要輸出的變量或表達(dá)式直接封裝在<%=和%>之中。<% Datedate=newDate(); out.print(date);%><%=date%>8).JSP腳本片斷(scriptlet)是指嵌套在<%和%>之中的一條或多條Java程序代碼。多個腳本片斷中的代碼可以相互訪問<% StringageStr=request.getParameter("age"); Integerage=Integer.parseInt(ageStr); if(age>=18){%> 成人...<% }else{%> 未成人...<% }%>9).JSP聲明:JSP聲明將Java代碼封裝在<%!和%>之中,它里面的代碼將被插入進(jìn)Servlet的_jspService方法的外面(在JSP頁面中幾乎從不這樣使用)10).JSP注釋的格式:<%--JSP注釋--%><!--HTML注釋-->區(qū)別:JSP注釋可以阻止Java代碼的執(zhí)行.六、和屬性相關(guān)的方法:1).方法voidsetAttribute(Stringname,Objecto):設(shè)置屬性O(shè)bjectgetAttribute(Stringname):獲取指定的屬性EnumerationgetAttributeNames():獲取所有的屬性的名字組成的Enumeration對象removeAttribute(Stringname):移除指定的屬性2).pageContext,request,session,application對象都有這些方法!這四個對象也稱之為域?qū)ο?pageContext:屬性的作用范圍僅限于當(dāng)前JSP頁面request:屬性的作用范圍僅限于同一個請求.(在轉(zhuǎn)發(fā)的情況下,可以跨網(wǎng)頁獲取屬性值)session:屬性的作用范圍限于一次會話:瀏覽器打開直到關(guān)閉稱之為一次會話(在此期間會話不失效)application:屬性的作用范圍限于當(dāng)前WEB應(yīng)用.是范圍最大的屬性作用范圍,只要在一處設(shè)置屬性,在其他各處的JSP或Servlet中都可以獲取到.(關(guān)閉服務(wù)器會銷毀當(dāng)前WEB應(yīng)用)Day3一、JSP指令:1.JSP指令(directive)是為JSP引擎而設(shè)計的,它們并不直接產(chǎn)生任何可見輸出,而只是告訴引擎如何處理JSP頁面中的其余部分?;靖袷剑?lt;%@指令屬性名="值"%><%@pagecontentType="text/html;charset=UTF-8"%>2.在目前的JSP2.0中,定義了page、include和taglib這三種指令3.page指令:1).page指令用于定義JSP頁面的各種屬性,無論page指令出現(xiàn)在JSP頁面中的什么地方,它作用的都是整個JSP頁面,為了保持程序的可讀性和遵循良好的編程習(xí)慣,page指令最好是放在整個JSP頁面的起始位置。2).page指令常用的屬性:①.import屬性:指定當(dāng)前JSP頁面對應(yīng)的Servlet需要導(dǎo)入的類.<%@pageimport="java.text.DateFormat"%>②.session屬性:取值為true或false,指定當(dāng)前頁面的session隱藏變量是否可用,也可以說訪問當(dāng)前頁面時是否一定要生成HttpSession對象.<%@pagesession="false"%>③.errorPage和isErrorPage屬性: >errorPage指定若當(dāng)前頁面出現(xiàn)錯誤時實際響應(yīng)頁面時什么.其中/表示的是當(dāng)前WEB應(yīng)用的根目錄. <%@pageerrorPage="/error.jsp"%> >在響應(yīng)error.jsp時,JSP引擎使用的請求轉(zhuǎn)發(fā)的方式. >isErrorPage指定當(dāng)前頁面是否為錯誤處理頁面,可以說明當(dāng)前頁面是否可以使用exception隱藏變量.需要注意的是:若指定 isErrorPage="true",并使用exception的方法了,一般不建議能夠直接訪問該頁面. >如何使客戶不能直接訪問某一個頁面呢?對于Tomcat服務(wù)器而言,WEB-INF下的文件是不能通過在瀏覽器中直接輸入地址的方式 來訪問的.但通過請求的轉(zhuǎn)發(fā)是可以的! >還可以在web.xml文件中配置錯誤頁面: <error> <!--指定出錯的代碼:404沒有指定的資源,500內(nèi)部錯誤.--> <error-code>404</error-code> <!--指定響應(yīng)頁面的位置--> <location>/WEB-INF/error.jsp</location> </error> <error> <!--指定異常的類型--> <exception-type>java.lang.ArithmeticException</exception-type> <location>/WEB-INF/error.jsp</location> </error> ④.contentType屬性:等同于response.setContentType(type),指定當(dāng)前JSP頁面的響應(yīng)類型.實際調(diào)用的是response.setContentType("text/html;charset=UTF-8");通常情況下,對于JSP頁面而言其取值均為text/html;charset=UTF-8.charset指定返回的頁面的字符編碼是什么.通常取值為UTF-8⑤.pageEncoding屬性:指定當(dāng)前JSP頁面的字符編碼.通常情況下該值和contentType中的charset一致.⑥.isELIgnored屬性:指定當(dāng)前JSP頁面是否可以使用EL表達(dá)式.通常取值為false. 4.include指令:<%@includefile="b.jsp"%>1).include指令用于通知JSP引擎在翻譯當(dāng)前JSP頁面時將其他文件中的內(nèi)容合并進(jìn)當(dāng)前JSP頁面轉(zhuǎn)換成的Servlet源文件中,這種在源文件級別進(jìn)行引入的方式稱之為靜態(tài)引入,當(dāng)前JSP頁面與靜態(tài)引入的頁面緊密結(jié)合為一個Servlet。2).file屬性的設(shè)置值必須使用相對路徑3).如果以/開頭,表示相對于當(dāng)前WEB應(yīng)用程序的根目錄(注意不是站點根目錄),否則,表示相對于當(dāng)前文件。推薦使用/方式來指明路徑j(luò)sp標(biāo)簽:jsp:include:1).<jsp:includepage="b.jsp"></jsp:include> 2).動態(tài)引入:并不是像include指令生成一個Servlet源文件,而是生成兩個Servlet源文件,然后通過一個方法的方式把目標(biāo)頁面包含進(jìn)來.org.apache.jasper.runtime.JspRuntimeLibrary.include(request,response,"b.jsp",out,false);2.jsp:forward:1).<jsp:forwardpage="/include/b.jsp"></jsp:forward> 相當(dāng)于. <% request.getRequestDispatcher("/include/b.jsp").forward(request,response);%>2).但使用jsp:forward可以使用jsp:param子標(biāo)簽向b.jsp傳入一些參數(shù).同樣jsp:include也可以使用jsp:param子標(biāo)簽.<jsp:forwardpage="/include/b.jsp"> <jsp:paramvalue="abcd"name="username"/></jsp:forward> OR<jsp:includepage="/include/b.jsp"> <jsp:paramvalue="abcd"name="username"/></jsp:include>在b.jsp頁面可以通過request.getParameter("username")獲取到傳入的請求參數(shù).三、關(guān)于中文亂碼:1).在JSP頁面上輸入中文,請求頁面后不出現(xiàn)亂碼:保證contentType="text/html;charset=UTF-8",pageEncoding="UTF-8"charset和pageEncoding的編碼一致,且都支持中文.通常建議取值為UTF-8還需保證瀏覽器的顯示的字符編碼也和請求的JSP頁面的編碼一致.2).獲取中文參數(shù)值:默認(rèn)參數(shù)在傳輸過程中使用的編碼為ISO-8859-1①.對于POST請求:只要在獲取請求信息之前(在調(diào)用request.getParameter或者是request.getReader等),調(diào)用request.setCharacterEncoding("UTF-8")即可.②.對于GET請求:前面的方式對于GET無效.因為tomcat默認(rèn)GET請求使用ISO-8859-1將傳輸數(shù)據(jù)編碼進(jìn)了URI可以在輸出前使用newString(str.getByte("iso-8859-1"),"UTF-8")進(jìn)行ISO-8859-1解碼后重新UTF-8編碼也可以通過修改Tomcat的server.xml文件來改變默認(rèn)URI的編碼參照http://localhost:8989/docs/config/index.html文檔的useBodyEncodingForURI屬性.為Connector節(jié)點添加useBodyEncodingForURI="true"屬性即可.<ConnectorconnectionTimeout="20000"port="8989"protocol="HTTP/1.1"redirectPort="8443"useBodyEncodingForURI="true"/>DAY4一、MVC:(前期)M:Model,DAO類V:View.jsp,在頁面上填寫Java代碼實現(xiàn)顯示C:Controller.Servlet,受理請求,獲取request中的參數(shù),調(diào)用DAO方法,根據(jù)實際需要將DAO返回值放入request中,轉(zhuǎn)發(fā)(或重定向)頁面轉(zhuǎn)發(fā)與重定向的選擇:若目標(biāo)的響應(yīng)界面不需要從request中獲取值,則可以使用重定向(重定向可以防止表單的重復(fù)提交)目前缺點:沒有使用數(shù)據(jù)庫連接池,DBUtils,JDBCUtil,工具類,DAO基類等應(yīng)該一個模塊一個Servlet而不是一個請求一個Servlet需要再頁面上加入jQuery提示,提高用戶體驗二、MVC案例需求:使用MVC設(shè)計模式實現(xiàn)對一張數(shù)據(jù)表的增刪改查1、沒有業(yè)務(wù)層,沒有事務(wù)操作,直接由Servlet調(diào)用DAO,DAO中可以直接獲取Connection對象2、MVC設(shè)計模式3、技術(shù):MVC設(shè)計模式,JSP,Servlet,POJO數(shù)據(jù)庫使用MySql數(shù)據(jù)庫連接池使用C3P0JDBC工具使用DBUtil頁面提示使用jQuery4、難點:多個請求如何共有一個Servlet:方法一、在請求URI后面設(shè)置參數(shù)和對應(yīng)的值比如?method=add/delete等缺點:URL暴露了方法,有安全隱患方法二、修改servlet映射,使用getServletPath區(qū)分每個請求,使用subString()去除多余部分,再調(diào)使用反射調(diào)用方法缺點:代碼量大如何實現(xiàn)模糊查詢根據(jù)傳入的name,address,phone進(jìn)行模糊查詢,例如name:a,address:b,phone:3sql語句為SELECTid,name,address,phoneFROMcontactsWHEREnameLIKE‘%a%’ANDaddressLIKE‘%b%’ANDphoneLIKE‘%3%’需要在ContactDAO接口中定義一個getForListWithCriteriaContact(CriteriaContactcc)方法CriteriaContact類用于封裝查詢條件,name,address,phone,因為查詢條件和domain類不一定相同,因此需要做成單獨的類拼寫sql:”SELECTid,name,address,phoneFROMcontactsWHEREnameLIKE?ANDaddressLIKE?ANDphoneLIKE?”;占位符無條件時為”%%”,有條件時為”%a%”Servlet中將請求參數(shù)分裝為CriteriaContact對象,將query方法中的getAll()(換為getForListWithCriteriaContact()(因為就是getAll()其實是模糊查詢的一種情況,當(dāng)模糊條件全是”%%”時)如何實現(xiàn)新增或修改時,驗證用戶名是否被占用,并給出提示刪除:超鏈接delete.do?=<%c.getId()%>servlet中獲取id,調(diào)用刪除方法,重定向到query.do(類似刷新頁面的效果,但需要在輸入框中保留查詢條件,此練習(xí)先不實現(xiàn))JSP中進(jìn)行jQuery提示:確認(rèn)刪除xxx的信息嗎,需要導(dǎo)入jquery.js才能使用jQuery語句,并添加<scripttype="text/javascript"src="scripts/jquery.js"></script>語句添加:設(shè)置超鏈接到newContact.jsp,在newContact.jsp中進(jìn)行添加Servlet中取出request中的信息,檢驗name是否重復(fù),調(diào)用添加方法之前獲取到數(shù)據(jù)表中相同name的數(shù)據(jù)條數(shù),條數(shù)大于0表示不可用,request中放入提示,重定向頁面,并且輸入框中保留之前的數(shù)據(jù),若條數(shù)等于0,調(diào)用save方法,重定向addSuccess.jsp頁面細(xì)節(jié),填入的信息不完整,需要提醒,字體顏色,回顯的地方需要判斷是否為null。修改:攜帶id到edit方法,方法中根據(jù)id從數(shù)據(jù)庫中獲取信息,并將信息轉(zhuǎn)發(fā)到修改界面,修改頁面獲取request中的信息,顯示出來,修改完成后,提示修改的id,id提前使用隱藏域保存(type=”hidden”),跳轉(zhuǎn)到query.do修改過程中要判斷name是否可用,name可以和舊的一樣(即不改name),但不能和其他的name一樣(修改了name)方法:保存舊名字,當(dāng)提交修改后,比較新舊name是否相同,相同,就不管name,不同再去數(shù)據(jù)庫尋找是否有重復(fù)的nameView:JSP呈現(xiàn)數(shù)據(jù),從request中取出參數(shù)接受用戶輸入3、View:JSP呈現(xiàn)數(shù)據(jù),從request中取出參數(shù)接受用戶輸入3、編寫JS代碼給出對應(yīng)提示Controller:Servlet1、獲取請求信息驗證請求參數(shù)的合法性,驗證失敗,給出提示將請求參數(shù)分裝為JavaBean調(diào)用DAO方法,獲取返回結(jié)果將返回結(jié)果放入request中響應(yīng)頁面(轉(zhuǎn)發(fā),重定向)Model:DAO1、獲取數(shù)據(jù)庫連接2、執(zhí)行增刪改查3、返回結(jié)果MySQL注意:不能跨層訪問,從右向左進(jìn)行編寫1.加入C3P0數(shù)據(jù)源:C3P0的jar包和c3p0-config.xml配置文件,數(shù)據(jù)庫驅(qū)動jar包2.編寫DAO,JDBCUtils工具類,ContactDAO接口3.提供ContactDAO接口的實現(xiàn)類4.Servlet映射為*.do5.doGet調(diào)用doPost方法,doPost中使用反射調(diào)用相應(yīng)的方法6.查詢流程:query.dodoPostquery(使用模糊查詢)JSP(獲取request的屬性值,遍歷)7.模糊查詢:SELECTid,name,address,phoneFROMcontactsWHEREnameLIKE?ANDaddressLIKE?ANDphoneLIKE?”;占位符無條件時為”%%”,有條件時為”%a%”,將篩選條件封裝成類,在封裝類中重寫get方法,該屬性為null時return”%%”,不為null時return”%”+屬性值+”%”三、深入理解面向接口編程在類中調(diào)用接口的方法,而不關(guān)心具體的實現(xiàn)方法,這有利于代碼的接口,是代碼具有更好的可移植性和可擴(kuò)展性。ContactDAOJdbcImplContactDAOXmlImplContactDAOContactServlet實現(xiàn)接口的方法使用接口的ContactDAOJdbcImplContactDAOXmlImplContactDAOContactServlet實現(xiàn)接口的方法使用接口的方法使用接口的方法通過修改類路徑下的properties文件,來動態(tài)改變Contacts的存儲方式1、Servlet中不能通過ContactDaodao=newContactDaoJdbcImpl()來獲得接口實現(xiàn)類對象2、應(yīng)該通過一個類的方法來獲取具體的實現(xiàn)類對象第一個啟動的服務(wù)器的init()方法中,讀取properties文件中的配置,得到type,并傳給工廠類工廠類:根據(jù)type屬性,返回不同的實現(xiàn)類對象ContactServlet:調(diào)用工廠類的方法,獲得實現(xiàn)類對象DAY5一、CookieCookie是完成會話跟蹤的一種機(jī)制,另一種是Ssessioncookie是由服務(wù)端產(chǎn)生的,瀏覽器(客戶端)訪問服務(wù)端時,服務(wù)器在Http的響應(yīng)頭中放入一個小文本文件傳給瀏覽器,這個文件就是cookie。一旦瀏覽器保存了cookie,在下一次訪問服務(wù)器時,會在Http請求頭中將cookie傳回給服務(wù)器默認(rèn)情況下cookie只能存在于一次會話中,臨時保存在瀏覽器內(nèi)存中,關(guān)閉瀏覽器后再次訪問時,瀏覽器需要重新獲取cookie持久性的cookie,設(shè)置cookie的最大有效時間,秒為單位,0表示立即刪除該cookie,負(fù)數(shù)表示不保存cookie自動登錄:需求:Login.jsp登錄后轉(zhuǎn)到index.jsp顯示name,在cookie有效期間,打開index.jsp可以直接顯示name,在cookie無效后,打開index.jsp會自動跳轉(zhuǎn)到login.jsp實現(xiàn):index.jsp界面,如果從request中獲取到的name不為null,則打印出Hello:XXXX,并設(shè)置cookie,最大有效時間為30s否則,如果可以從request中直接獲取到cookie,且length>0,則讀取用戶信息,并打印出Hello:XXXX上兩種都不滿足,則重定向到login.jsp顯示最近瀏覽的五本書需求:books.jsp界面選擇書名,跳轉(zhuǎn)到book.jsp瀏覽詳情,return,回到books.jsp界面,可以看到下方有剛剛瀏覽的書的名字,最多可以顯示五本,且最新書名的會把最舊的頂下去實現(xiàn):books.jsp界面:獲取所有cookie找出和書名相關(guān)的cookie,顯示cookievaluebook.jsp界面:取出所有的cookie,遍歷篩選出保存書名的cookie(startWith()),保存到list中同時判斷是否有重復(fù)的書名,有重復(fù),則刪除|||||||無重復(fù)有重復(fù)(已被刪除了)||||||||||||list.length>=5list.length<5|||||||\/\/\/刪除最舊的cookie添加新cookieCookie作用域cookie的默認(rèn)的作用范圍為當(dāng)前目錄和子目錄,即當(dāng)前目錄寫入的可以被當(dāng)前目錄和子目錄讀取,不能被其他目錄的讀取可以手動修改cookie的作用范圍"/"表示站點根目錄補(bǔ)充request.getContextPath()返回當(dāng)前WEB應(yīng)用根目錄二、Session當(dāng)客戶端請求創(chuàng)建一個session時,服務(wù)器先檢查請求中是否有sessionid的cookie,若包含,則服務(wù)器會去檢索id對應(yīng)的session對象,若不包含,服務(wù)器則會創(chuàng)建一個session對象,并將sessionid用cookie的方式響應(yīng)給客戶端。1、Session的生命周期1)什么時候創(chuàng)建HttpSession對象:對于JSP:如果當(dāng)前JSP是客戶端在WEB應(yīng)用的中訪問的第一頁面,session為true時,則JSP會創(chuàng)建session對象,session為false時,則不會創(chuàng)建session對象;如果客戶端在訪問當(dāng)前JSP之前已經(jīng)訪問過同一個WEB應(yīng)用的其他JSP,而且之前訪問的JSP已經(jīng)為其創(chuàng)建了session對象,當(dāng)前JSP就會返回之前那個session對象,而不會創(chuàng)建一個新的,不論當(dāng)前JSP頁面session屬性是true或false對于Servlet:如果當(dāng)前servlet是客戶端在WEB應(yīng)用的中訪問的第一個資源,只有調(diào)用了request.getSession()或request.getSession(true)才會創(chuàng)建session對象,否則不會創(chuàng)建;如果客戶端在訪問當(dāng)前servlet之前已經(jīng)訪問過同一個WEB應(yīng)用的其他servlet,而且之前訪問的servlet已經(jīng)為其創(chuàng)建了session對象,當(dāng)前servlet就會返回之前那個session對象,而不會創(chuàng)建一個新的。Session=”false”:頁面禁用隱式session,就是不能直接session.方法,但可以使用顯式session,自己創(chuàng)建一個session,比如HttpSessionsession=request.getSession()2)關(guān)于request.getSession(flag)方法若flag為true,則一定會返回一個HttpSession對象,如果已經(jīng)有和當(dāng)前JSP頁面關(guān)聯(lián)的HttpSession對象,直接返回;如果沒有,則創(chuàng)建一個新的返回.flag為false:若已經(jīng)存在關(guān)聯(lián)的session,則返回;若沒有,則返回null;request.getSession():相當(dāng)于request.getSession(true)3)什么時候銷毀Httpsession對象:①.直接調(diào)用HttpSession的invalidate()②.HttpSession超過過期時間. >返回最大時效:getMaxInactiveInterval()單位是秒 >設(shè)置最大時效:setMaxInactiveInterval(intinterval) >可以在tomacat配置目錄下的web.xml文件中配置Session的最大時效,單位是分鐘. <session-config><session-timeout>30</session-timeout></session-config>③.卸載當(dāng)前WEB應(yīng)用.注意:關(guān)閉瀏覽器不會銷毀Session!2、如何在瀏覽器禁用cookie的情況下使用sessionURL重寫:將URL改為response.encodeURL(URL)或encodeRedirectURL()原理:將sessionID以參數(shù)的形式附加在URL地址后面3、簡版session購物車4、路徑問題:開發(fā)時建議寫絕對路徑。絕對路徑:相對于當(dāng)前WEB應(yīng)用的根目錄(request.getContextPath())的路徑,即相對路徑都必須帶上當(dāng)前WEB應(yīng)用的根目錄,相對于站點根目錄的路徑不算。http://localhost:8080/request.getContextPath()/A.jsp是相對路徑http://localhost:8080/A.jsp不是相對路徑路徑中的第一個“/”:表示W(wǎng)EB應(yīng)用根目錄:WEB.xml文件中的映射路徑、請求轉(zhuǎn)發(fā)(由servlet解析的路徑)表示站點根目錄:a標(biāo)簽的href屬性、from標(biāo)簽中的action屬性、請求重定向(由瀏覽器解析的路徑)5、表單的重復(fù)提交1)重復(fù)提交的情況:①.在表單提交到一個Servlet,而Servlet又通過請求轉(zhuǎn)發(fā)的方式響應(yīng)一個JSP(HTML)頁面,此時地址欄還保留著Serlvet的那個路徑,在響應(yīng)頁面點擊"刷新"②.在響應(yīng)頁面沒有到達(dá)時重復(fù)點擊"提交按鈕".③.點擊"返回",再點擊"提交",(返回的是緩存頁面,沒有執(zhí)行java代碼)2)不是重復(fù)提交的情況:點擊"返回","刷新"原表單頁面,再"提交"。3).如何避免表單的重復(fù)提交:在表單中做一個標(biāo)記,提交到Servlet時,檢查標(biāo)記是否存在且是否和預(yù)定義的標(biāo)記一致,若一致,則受理請求,并銷毀標(biāo)記,若不一致或沒有標(biāo)記,則直接響應(yīng)提示信息:"重復(fù)提交"①.僅提供一個隱藏域:<inputtype="hidden"name="token"value="atguigu"/>.行不通:沒有方法清除標(biāo)記.只有removeAttribute(),沒有removeParameter(),此處的標(biāo)記是參數(shù)而不是屬性②.使用setAttribute()把標(biāo)記放在reques中.此方法行不通,因為瀏覽器訪問JSP頁面的request和JSP通過表單提交方式訪問servlet的request不是同一個.JSP頁面中setAttribute()是針對瀏覽器訪問JSP頁面的request,而在servlet中g(shù)etAttribute()是針對JSP訪問servlet的request。③.把標(biāo)記放在session中.可以! >在原表單頁面,生成一個隨機(jī)值keyValueStringkeyValue=newDate().getTime()+""; >在原表單頁面,把keyValue值放入session屬性中 >在原表單頁面,把keyValue值放入到隱藏域中. >在目標(biāo)的Servlet中:獲取session和隱藏域中的token值 >比較兩個值是否一致:若一致,受理請求,且把session域中的token屬性清除 >若不一致,則直接響應(yīng)提示頁面:"重復(fù)提交"優(yōu)勢:對比①:session可以setAttribute()也可以removeAttribute()對比②:session存在于會話中,可以跨頁面訪問同一個,而request要實現(xiàn)多頁面?zhèn)鬏斨荒苤挥棉D(zhuǎn)發(fā),提交表單會產(chǎn)生新的requestbb6、使用HttpSession實現(xiàn)驗證碼1).基本原理:和表單重復(fù)提交一致: >在原表單頁面,生成一個驗證碼的圖片,生成圖片的同時,需要把該圖片中的字符串放入到session中. >在原表單頁面,定義一個文本域,用于輸入驗證碼. >在目標(biāo)的Servlet中:獲取session和表單域中的驗證碼的值 >比較兩個值是否一致:若一致,受理請求,且把session域中的驗證碼屬性清除 >若不一致,則直接通過重定向的方式返回原表單頁面,并提示用戶"驗證碼錯誤"Day6一、EL:1、特性:1)Scope表示在指定范圍內(nèi)尋找customer對象如果不指明范圍,則依次從>request->session->application找,找到就返回對象,沒找到返回null2)例如customer.age這樣的帶符號的屬性名,只能使用[]中括號[“customer.age”]${sessionScope["customer.age"].age}3)el可以自動類型轉(zhuǎn)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 13年土地轉(zhuǎn)讓合同范本
- 2023屆新高考化學(xué)一輪復(fù)習(xí)鹽類的水解提能力
- 門窗合同范本簡易
- 五年級數(shù)學(xué)上冊 4.多邊形的面積 (含詳解)(北師大版)
- 轉(zhuǎn)包抽成合同范本
- 理財利息合同范本
- 2023年云南玉溪農(nóng)業(yè)職業(yè)技術(shù)學(xué)院招聘畢業(yè)生考試真題
- 2023年新鄉(xiāng)獲嘉縣消防救援大隊招聘政府專職消防員考試真題
- 2023年云南省曲靖一中卓立學(xué)校招聘公費(fèi)師范生筆試真題
- 2023年陜西航天醫(yī)院招聘考試真題
- 醫(yī)院健康教育培訓(xùn)課件
- GH/T 1419-2023野生食用菌保育促繁技術(shù)規(guī)程灰肉紅菇
- ISO9001:2015標(biāo)準(zhǔn)內(nèi)容講解
- 高一英語語法知識點北師大
- 鼻咽癌的放射治療課件
- 明孝端皇后九龍九鳳冠
- 生殖實驗室簡介課件
- 注塑車間規(guī)劃方案
- 生豬屠宰廠員工培訓(xùn)方案
- 營養(yǎng)不良五階梯治療
- 裝修項目的工程量清單
評論
0/150
提交評論