购买

¥ 30.0

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 第三章-Servlet-编程-v3.0

第三章-Servlet-编程-v3.0.ppt

第三章-Servlet-编程-v3.0

烟雨梦兮
2018-10-14 0人阅读 举报 0 0 暂无简介

简介:本文档为《第三章-Servlet-编程-v3.0ppt》,可适用于IT/计算机领域

第三章Servlet编程baolugaocom课程名称:软件代码开发技术教材:《JavaEE编程技术》(清华大学、北京交通大学出版社)主讲:高保禄单位:太原理工大学计算机与软件学院时间:年月*本章主要内容Servlet基础Servlet编程基本技能Servlet编程高级技能ServletFilter编程ServletListener编程*Servlet基础√Servlet编程基本技能Servlet编程高级技能ServletFilter编程ServletListener编程*Servlet基础Servlet定义:一种独立于操作系统平台和网络传输协议的服务器端的Java应用程序它用来扩展服务器的功能可以生成动态的Web页面注意:Servlet不是从命令行启动的而是由包含Java虚拟机的Web服务器进行加载*JavaServletsAservletisaJavatechnologycomponentthatexecutesontheserverServletsperformtaskssimilartothoseperformedbyCGIprograms,butservletsexecuteinadifferentenvironmentServletsperformthefollowing:ProcesstheHTTPrequestGeneratetheHTTPresponsedynamicallyAwebcontainerisaspecialJava™VirtualMachine(JVM™)thatisresponsibleformaintainingthelifecycleoftheservlets,aswellasissuingthreadsforeachrequest*Servlet基础Servlet与Applet相比较:相似之处:()它们不是独立的应用程序没有main()方法。()它们不是由用户调用而是由另外一个应用程序(容器)调用。()它们都有一个生存周期包含init()和destroy()方法。不同之处:()Applet运行在客户端具有丰富的图形界面。()Servlet运行在服务器端没有图形界面。*Servlet最大的用途是通过动态响应客户机请求来扩展服务器功能!!!!Servlet基础*Servlet基础Servlet工作原理:Servlet运行在Web温<H><td><tr><TABLE>")outprint("<FORMACTION="")outprintln(responseencodeURL("adminTemperature"))outprintln(""METHOD="POST">")outprintln("当前气温(摄氏度)")outprintln("<INPUTTYPE="text"NAME="temperature"""VALUE="Temperature">")outprintln("<INPUTTYPE="Submit"NAME="btnsubmit"""VALUE="更新">")outprintln("<FORM><BODY><HTML>")}**HandlestheHTTP<code>POST<code>method*paramrequestservletrequest*paramresponseservletresponse*protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{responsesetContentType("texthtmlcharset=gb")PrintWriterout=responsegetWriter()StringTemperature=requestgetParameter("temperature")将更新后的气温信息放入上下文getServletContext()setAttribute("Temperature",Temperature)outprintln("<HTML><HEAD><TITLE>气温更新""<TITLE><HEAD>")outprintln("<BODY>")outprintln("当前气温:"Temperature"摄氏度")outprintln("<BODY><HTML>")}**Returnsashortdescriptionoftheservlet*publicStringgetServletInfo(){return"Shortdescription"}<editorfold>}**ShowTemperatureServletjava**Createdon年月日,下午:*packagecomservletimportjavaio*importjavanet*importjavaxservlet*importjavaxservlethttp*****authorhyl*version*publicclassShowTemperatureServletextendsHttpServlet{**ProcessesrequestsforbothHTTP<code>GET<code>and<code>POST<code>methods*paramrequestservletrequest*paramresponseservletresponse*protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{responsesetContentType("texthtmlcharset=gb")PrintWriterout=responsegetWriter()StringTemperature=(String)getServletContext()getAttribute("Temperature")if(Temperature==){Temperature=newString("")}StringoldTemperature=(String)requestgetSession()getAttribute("OldTemperature")outprintln("<HTML><HEAD><TITLE>气温信息显示""<TITLE><HEAD>")outprintln("<BODY>")outprintln("当前最新气温:"Temperature"摄氏度")if(oldTemperature!=){outprintln("<BR>")outprintln("更新前气温:"oldTemperature"摄氏度")}outprintln("<BODY><HTML>")更新会话中的气温信息requestgetSession()setAttribute("OldTemperature",Temperature)}<editorfolddefaultstate="collapsed"desc="HttpServletmethodsClickonthesignonthelefttoeditthecode">**HandlestheHTTP<code>GET<code>method*paramrequestservletrequest*paramresponseservletresponse*protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}**HandlestheHTTP<code>POST<code>method*paramrequestservletrequest*paramresponseservletresponse*protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}**Returnsashortdescriptionoftheservlet*publicStringgetServletInfo(){return"Shortdescription"}<editorfold>}*<!DOCTYPEHTMLPUBLIC"WCDTDHTMLTransitionalEN"><htmllang='zh'><head><title>登录<title><head><bodybgcolor="#FFFFFF"><center>欢迎登录系统<center><formname="login"method="post"action="Main"><label>用户名:<label><inputtype=textname="userID"value=""><label>密码:<label><inputtype=passwordname="password"value=""><inputtype="submit"name="tj"value="提交"><input><inputtype="reset"name="reset"><input><form><body><html>**Mainjava**Createdon年月日,下午:*packagecomservletimportjavaio*importjavaxservlet*importjavaxservlethttp*publicclassMainextendsHttpServlet{protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{Systemoutprintln("我在ServletMain中")try{Threadsleep()}catch(InterruptedExceptionie){Systemoutprintln(ietoString())}StringuserID=requestgetParameter("userID")if(userID==)userID=""Stringpassword=requestgetParameter("password")if(password==)password=""if((userIDequals("guest")passwordequals("guest"))){RequestDispatcherdispatcher=requestgetRequestDispatcher("LoginSuccess")dispatcherforward(request,response)}else{RequestDispatcherdispatcher=requestgetRequestDispatcher("LoginFail")dispatcherforward(request,response)}}protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}publicStringgetServletInfo(){return"Shortdescription"}}**LoginSuccessjava**Createdon年月日,下午:*packagecomservletimportjavaio*importjavanet*importjavaxservlet*importjavaxservlethttp*publicclassLoginSuccessextendsHttpServlet{protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{responsesetContentType("texthtmlcharset=")PrintWriterout=responsegetWriter()Stringname=requestgetParameter("userID")outprintln("<html>")outprintln("<head>")outprintln("<title>登录成功<title>")outprintln("<head>")outprintln("<body>")outprintln("<h>欢迎!"name"您已成功登录系统<h>")outprintln("<body>")outprintln("<html>")outclose()}protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}publicStringgetServletInfo(){return"Shortdescription"}<editorfold>}**LoginFailjava**Createdon年月日,下午:*packagecomservletimportjavaio*importjavanet*importjavaxservlet*importjavaxservlethttp*publicclassLoginFailextendsHttpServlet{protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{responsesetContentType("texthtmlcharset=")PrintWriterout=responsegetWriter()outprintln("<html>")outprintln("<head>")outprintln("<title>登录失败<title>")outprintln("<head>")outprintln("<body>")outprintln("<h>登录失败请重新登录<h>")RequestDispatcherdispatcher=requestgetRequestDispatcher("dlhtml")dispatcherinclude(request,response)outprintln("<body>")outprintln("<html>")outclose()}protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}publicStringgetServletInfo(){return"Shortdescription"}<editorfold>}***TimeTrackFilterjava**Createdon年月日,下午:*packagecomservletimportjavaio*importjavautil*importjavaxservletFilterimportjavaxservletFilterChainimportjavaxservletFilterConfigimportjavaxservletServletExceptionimportjavaxservletServletRequestimportjavaxservletServletResponse****authorhyl*version*publicclassTimeTrackFilterimplementsFilter{privateFilterConfigfilterConfig=publicvoidinit(FilterConfigfilterConfig)throwsServletException{thisfilterConfig=filterConfig}publicvoiddestroy(){thisfilterConfig=}publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{DatestartTime,endTimedoubletotalTimeStringWritersw=newStringWriter()Systemoutprintln("我在Filter中")startTime=newDate()chaindoFilter(request,response)endTime=newDate()totalTime=endTimegetTime()startTimegetTime()totalTime=totalTimeSystemoutprintln("我在Filter中")PrintWriterwriter=newPrintWriter(sw)writerprintln("===============")writerprintln("耗时:"totalTime"毫秒")writerprintln("===============")filterConfiggetServletContext()log(swgetBuffer()toString())}}***Tochangethistemplate,chooseTools|Templates*andopenthetemplateintheeditor*packagecomgbllistenerimportjavaxservlethttpHttpSessionAttributeListenerimportjavaxservlethttpHttpSessionBindingEventimportjavaxservlethttpHttpSessionEventimportjavaxservlethttpHttpSessionListener***Webapplicationlifecyclelistener*authorfrank*publicclassNewServletListenerimplementsHttpSessionListener,HttpSessionAttributeListener{publicvoidsessionCreated(HttpSessionEventse){Systemoutprintln("hellosessionCreated")}publicvoidsessionDestroyed(HttpSessionEventse){Systemoutprintln("hellosessionDestroyed")}publicvoidattributeAdded(HttpSessionBindingEventse){Systemoutprintln("helloattribueAdded")Systemoutprintln(segetSession()getAttribute("userName"))Systemoutprintln(segetSession()getServletContext()getServerInfo())segetSession()getServletContext()getRequestDispatcher("gaobaolujsp")forward(request,response)}publicvoidattributeRemoved(HttpSessionBindingEventse){Systemoutprintln("helloattributeRemoved")}publicvoidattributeReplaced(HttpSessionBindingEventse){Systemoutprintln("helloattributeReplaced")}}<Document:indexCreatedon:,::Author:frank><pagecontentType="texthtml"pageEncoding=""><!DOCTYPEHTMLPUBLIC"WCDTDHTMLTransitionalEN""http:wwwworgTRhtmlloosedtd"><html><head><metahttpequiv="ContentType"content="texthtmlcharset="><title>JSPPage<title><head><body><h>HelloWorld!<h><sessionsetAttribute("userName","gaobaolu")><=sessiongetAttribute("userName")><sessionremoveAttribute("userName")><sessioninvalidate()><body><html>*HttpSession监听器实例学习目标:了解如何使用HttpSessionListener了解如何使用HttpSessionAttributeListener了解如何使用HttpSessionBindingListener说明:、HttpSessionListener接口该接口用来监听Web应用中session列表的改变并在某个session对象建立和销毁之前执行一些用户行为【接口方法】sessionCreated()与sessionDestroyed()【接收事件】HttpSessionEvent(通过事件可以得到发生变化的session对象)【触发场景】在一个session(HttpSession)对象建立或被消灭时会分别触发sessionCreated()和sessionDestroyed()方法。、HttpSessionAttributeListener接口该接口用来监听某个session的属性列表的变化并在变化发生后执行一些用户行为。【接口方法】attributeAdded()、attributeReplaced()、attributeRemoved()【接收事件】HttpSessionBindingEvent(通过事件可以得到变化的session以及变化的属性的Name和Value)【触发场景】若有属性加入到某个session(HttpSession)对象则会触发attributeAdded()同理在替换属性与移除属性时会分别触发attributeReplaced()、attributeRemoved()。、HttpSessionBindingListener接口【接口方法】valueBound()与valueUnbound()【接收事件】HttpSessionBindingEvent(通过事件可以得到变化的session以及变化的属性的Name和Value)【触发场景】实现HttpSessionBindingListener接口的类其实例如果被加入至session(HttpSession)对象的属性中则会触发valueBound()如果被从session(HttpSession)对象的属性中移除则会触发valueUnbound()实现HttpSessionBindingListener接口的类不需在webxml中注册。实例:resultssessioncreatedattributeaddedattributereplacedattributeremoved>>>>>SessionBindingListenerTestvalueBoundattributeadded>>>>>SessionBindingListenerTestvalueUnboundattributereplacedattributeremovedsessiondestroyedindexjsp<pagecontentType="texthtml"pageEncoding=""><pageimport="comgbl*"><!DOCTYPEHTMLPUBLIC"WCDTDHTMLTransitionalEN""http:wwwworgTRhtmlloosedtd"><html><head><metahttpequiv="ContentType"content="texthtmlcharset="><title>JSPPage<title><head><body><h>HelloWorld!<h><sessionsetAttribute("loginName","gaobaolu")sessionsetAttribute("loginName","admin")sessionremoveAttribute("loginName")sessionsetAttribute("bindingObject",newSessionBindingListenerTest())HttpSessionBindingLister监听器很特别它只监听实现该监听器类的实例sessionsetAttribute("bindingObject","otherObject")会触发valueUnbound()sessionremoveAttribute("bindingObject")如果没有上面语句这里也会触发valueUnbound()sessioninvalidate()如果没有上面,语句这里也会触发valueUnbound()><body><html>webxml<xmlversion=""encoding=""><webappversion=""xmlns="http:javasuncomxmlnsjavaee"xmlns:xsi="http:wwwworgXMLSchemainstance"xsi:schemaLocation="http:javasuncomxmlnsjavaeehttp:javasuncomxmlnsjavaeewebappxsd"><listener><description>HttpSessionListener<description><listenerclass>comgblSessionListenerTest<listenerclass><listener><listener><description>HttpSessionAttributeListener<description><listenerclass>comgblSessionAttributeListenerTest<listenerclass><listener><sessionconfig><sessiontimeout><sessiontimeout><sessionconfig><welcomefilelist><welcomefile>indexjsp<welcomefile><welcomefilelist><webapp>SessionListenerTestjavapackagecomgblimportjavaxservlethttpHttpSessionEventimportjavaxservlethttpHttpSessionListenerpublicclassSessionListenerTestimplementsHttpSessionListener{publicvoidsessionCreated(HttpSessionEventarg){thrownewUnsupportedOperationException("Notsupportedyet")Systemoutprintln("sessioncreated")}publicvoidsessionDestroyed(HttpSessionEventarg){thrownewUnsupportedOperationException("Notsupportedyet")Systemoutprintln("sessiondestroyed")}}SessionAttributeListenerTestjavapackagecomgblimportjavaxservlethttpHttpSessionAttributeListenerimportjavaxservlethttpHttpSessionBindingEventpublicclassSessionAttributeListenerTestimplementsHttpSessionAttributeListener{publicvoidattributeAdded(HttpSessionBindingEventarg){thrownewUnsupportedOperationException("Notsupportedyet")Systemoutprintln("attributeadded")}publicvoidattributeRemoved(HttpSessionBindingEventarg){thrownewUnsupportedOperationException("Notsupportedyet")Systemoutprintln("attributeremoved")}publicvoidattributeReplaced(HttpSessionBindingEventarg){thrownewUnsupportedOperationException("Notsupportedyet")Systemoutprintln("attributereplaced")}}SessionBindingListenerTestjavapackagecomgblimportjavaxservlethttp*publicclassSessionBindingListenerTestimplementsHttpSessionBindingListener{ publicvoidvalueBound(HttpSessionBindingEventarg){thrownewUnsupportedOperationException("Notsupportedyet")Systemoutprintln(">>>>>SessionBindingListenerTestvalueBound")}publicvoidvalueUnbound(HttpSessionBindingEventarg){thrownewUnsupportedOperationException("Notsupportedyet")Systemoutprintln(">>>>>SessionBindingListenerTestvalueUnbound")}}***CounterFilejava**Createdon年月日,下午:**Tochangethistemplate,chooseTools|TemplateManager*andopenthetemplateintheeditor*packagecomservlet****authorhyl*importjavaioBufferedReaderimportjavaioFileNotFoundExceptionimportjavaioFileOutputStreamimportjavaioFileReaderimportjavaioIOExceptionimportjavaioPrintWriter用来操作记录访问次数的文件publicclassCounterFile{privateBufferedReaderfileBufferedReader对象用于读取文件数据publicCounterFile(){}ReadFile方法用来读取文件filePath中的数据并返回这个数据publicStringReadFile(StringfilePath)throwsFileNotFoundException{StringcurrentRecord=保存文本的变量创建新的BufferedReader对象file=newBufferedReader(newFileReader(filePath))StringreturnStr=try{读取一行数据并保存到currentRecord变量中currentRecord=filereadLine()}catch(IOExceptione){错误处理Systemoutprintln("读取数据错误")}if(currentRecord==)如果文件为空returnStr="没有任何记录"else{文件不为空returnStr=currentRecord}返回读取文件的数据returnreturnStr}ReadFile方法用来将数据counter后写入到文本文件filePath中以实现计数增长的功能publicsynchronizedvoidWriteFile(StringfilePath,Stringcounter)throwsFileNotFoundException{intWritestr=Writestr=IntegerparseInt(counter)try{创建PrintWriter对象用于写入数据到文件中PrintWriterpw=newPrintWriter(newFileOutputStream(filePath))用文本格式打印整数Writestrpwprintln(Writestr)清除PrintWriter对象pwclose()}catch(IOExceptione){错误处理Systemoutprintln("写入文件错误"egetMessage())}}}**CounterListenerjava**Createdon年月日,下午:*packagecomservletimportjavaxservletServletContextListenerimportjavaxservletServletContextEventpublicclassCounterListenerimplementsServletContextListener{Stringpath=""publicvoidcontextInitialized(ServletContextEventevt){CounterFilef=newCounterFile()Stringname=evtgetServletContext()getInitParameter("CounterPath")path=evtgetServletContext()getRealPath(name)try{Stringtemp=fReadFile(path)Systemoutprintln(temp)evtgetServletContext()setAttribute("Counter",temp)将计数器的值放入应用上下文}catch(Exceptione){Systemoutprintln(etoString())}}publicvoidcontextDestroyed(ServletContextEventevt){try{Stringcurrent=(String)evtgetServletContext()getAttribute("Counter")CounterFilef=newCounterFile()fWriteFile(path,current)}catch(Exceptione){Systemoutprintln(etoString())}}}**SessionListenerjava**Createdon年月日,下午:**Tochangethistemplate,chooseTools|TemplateManager*andopenthetemplateintheeditor*packagecomservletimportjavaxservlethttpHttpSessionListenerimportjavaxservlethttpHttpSessionEventpublicclassSessionListenerimplementsHttpSessionListener{publicvoidsessionCreated(HttpSessionEventevt){修改在线人数Stringcurrent=(String)evtgetSession()getServletContext()getAttribute("online")if(current==)current=""intc=IntegerparseInt(current)ccurrent=StringvalueOf(c)evtgetSession()getServletContext()setAttribute("online",current)修改历史人数Stringhis=(String)evtgetSession()getServletContext()getAttribute("Counter")if(his==)his=""inttotal=IntegerparseInt(his)his=StringvalueOf(total)evtgetSession()getServletContext()setAttribute("Counter",his)}publicvoidsessionDestroyed(HttpSessionEventevt){TODO在此处添加您的代码:修改在线人数Stringcurrent=(String)evtgetSession()getServletContext()getAttribute("online")if(current==)current=""intc=IntegerparseInt(current)ccurrent=StringvalueOf(c)evtgetSession()getServletContext()setAttribute("online",current)}}**Counterjava**Createdon年月日,下午:*packagecomservletimportjavaio*importjavanet*importjavaxservlet*importjavaxservlethttp*****authorhyl*version*publicclassCounterextendsHttpServlet{**ProcessesrequestsforbothHTTP<code>GET<code>and<code>POST<code>methods*paramrequestservletrequest*paramresponseservletresponse*protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{responsesetContentType("texthtmlcharset=")PrintWriterout=responsegetWriter()Stringhistory=(String)getServletContext()getAttribute("Counter")if(history==)history=""intlast=IntegerparseInt(history)Stringtemp=(String)getServletContext()getAttribute("online")if(temp==)temp=""intonline=IntegerparseInt(temp)outprintln("<html>")outprintln("<head>")outprintln("<title>计数器<title>")outprintln("<head>")outprintln("<body>")outprintln("<h>当前访问人数:"temp"<h>")outprintln("<h>历史访问人数:"history"<h>")outprintln("<body>")outprintln("<html>")outclose()}<editorfolddefaultstate="collapsed"desc="HttpServletmethodsClickonthesignonthelefttoeditthecode">**HandlestheHTTP<code>GET<code>method*paramrequestservletrequest*paramresponseservletresponse*protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}**HandlestheHTTP<code>POST<code>method*paramrequestservletrequest*paramresponseservletresponse*protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{processRequest(request,response)}**Returnsashortdescriptionoftheservlet*publicStringgetServletInfo(){return"Shortdescription"}<editorfold>}*补充说明:HttpSessionBindingListenerinterfaceisimplementedbyobjectsthatwanttobenotifiedwhentheyareboundtoasessionorunboundfromasessionwhentheyboundorunboundtothesessionHttpSessionBindingListenersimplementthevalueBoundandvalueUnboundmethodsForHttpSessionAttributeListener,theclassthatimplementsthisinterfacemustbespecifiedintheDeploymentDescriptorWheneveranysessionattributesareadded,removedandreplaced,itwillbenotifiedHttpSessionAttributeListenersimplementtheattributeAdded,attributeRemovedandattributeReplacedmethodsAwebapplicationwhichhasaHttpSessionAttributeListenerwouldnormallyhaveonesuchlistenerwhichwouldhandleallattributesandallsessionsConclusion:HttpSessionBindingListenerdealswithonesessionobjectandHttpSessionBindingListenersareuniquetoparticularobjectsIftwoclassesofobjectsimplementthislistener,theimplementationscouldbecompletelydifferentOneclasscouldimplementanemptyvalueBound()methodandtheotherclasscouldimplementafunctionalvalueBound()methodIfanobjectimplementsHttpSessionBindingListener,itsvalueBoundandvalueUnboundmethodsareonlyinvokedwhenthatparticularobjectisboundtoasessionorunboundfromasessionHttpSessionAttributeListenerinstanceiscreatedbyWebContainer,basedon<listern>elementinwebxmlForeach<listernclass>,onelisterninstanceiscreatedHttpSessionAttributeListenerdealswithallavailablesessionobjectsBasically,HttpSessionAttributeListenerisimplementedbyanobjectthatisinterestedinreceivingeventsfromallthesessionsbelongingtotheapplication,whileHttpSessionBindingListenerisimplementedbytheobjectattributesfortheparticularsessiontowhichtheyareaddedorremoved

VIP尊享8折文档

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/80

第三章-Servlet-编程-v3.0

¥30.0

会员价¥24.0

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利