当前位置: 首页 > news >正文

营销型网站建设菲凡网好用的做图网站有哪些

营销型网站建设菲凡网,好用的做图网站有哪些,网站的管理系统,网页设计怎样做一个网页Day40 监听器 概念#xff1a; 监听器用于监听web应用中某些对象信息的创建、销毁、增加#xff0c;修改#xff0c;删除等动作的 发生#xff0c;然后作出相应的响应处理。当范围对象的状态发生变化的时候#xff0c;服务器自动调用 监听器对象中的方法。 常用于统计在线…Day40 监听器 概念 监听器用于监听web应用中某些对象信息的创建、销毁、增加修改删除等动作的 发生然后作出相应的响应处理。当范围对象的状态发生变化的时候服务器自动调用 监听器对象中的方法。 常用于统计在线人数和在线用户系统加载时进行信息初始化统计网站的访问量等。 类别 第一大类监听请求域、会话域、全局域对象的创建和销毁。 第二大类监听请求域、会话域、全局域对象的属性的创建、替换、销毁。 第三大类监听会话域String key - Object value里value的绑定和解绑、钝化和活化。 第一大类 监听请求域 servlet package com.qf.servlet;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; WebServlet(/Servlet01) public class Servlet01 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(执行Servlet);} }web.xml: listenerlistener-classcom.qf.listen.MyServletRequestListener/listener-class/listenerlistener: package com.qf.listen;import javax.servlet.ServletRequest; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener;public class MyServletRequestListener implements ServletRequestListener {Overridepublic void requestDestroyed(ServletRequestEvent servletRequestEvent) {ServletRequest request servletRequestEvent.getServletRequest();System.out.println(请求对象被销毁了request);}Overridepublic void requestInitialized(ServletRequestEvent servletRequestEvent) {ServletRequest request servletRequestEvent.getServletRequest();System.out.println(请求对象被创建了request);} } 注请求对象的生命周期为创建客户端发送请求服务器会创建请求对象。销毁服务器返回响应后会把请求对象、响应对象一并销毁。 监听会话域 注意查看生命周期要把index.jsp改名或者删除因为项目启动会默认进入index.jsp会创建会话对象。 web.xml:手动调整session销毁时间 listenerlistener-classcom.qf.listen.MyHttpSessionListener/listener-class/listenersession-configsession-timeout1/session-timeout/session-config创建一个page01.jsp。 MyHttpSessionListener: package com.qf.listen;import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener;public class MyHttpSessionListener implements HttpSessionListener {Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {HttpSession session httpSessionEvent.getSession();System.out.println(会话对象被创建了session.getId());}Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {System.out.println(会话对象被销毁了);} } 注会话对象的什么周期创建服务器使用到了session-request.getSession();销毁session对象设置的过期时间到后就会被销毁。 思考1客户端访问html资源是否会创建会话对象答不会 思考2客户端访问jsp资源会创建会话对象为什么答会因为jsp里9大内置对象中有session对象。 思考3session对象创建后客户端发送下一次请求是为什么能找到之前的session对象答因为客户端在cookie中存储了session的id-JSESSIONID 思考4session对象是存活在服务器中的默认为30分钟的生命周期可客户端存储的cookie里的JSESSIONID为会话结束时也就意味着关闭浏览器后再也找不到之前存储在服务器中的session对象那怎么解决 答设置cookie中JSESSION的过期时间。 package com.qf.servlet;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; WebServlet(/Servlet01) public class Servlet01 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(Servlet收到请求);HttpSession session request.getSession();Cookie cookie new Cookie(JSESSION,session.getId());cookie.setMaxAge(60*30);response.addCookie(cookie);response.getWriter().println(abc);} }监听全局域 web.xml: context-paramparam-nameinfo/param-nameparam-valueabc/param-value/context-paramlistenerlistener-classcom.qf.listen.MyServletContextListener/listener-class/listenerMyServletContextListener: package com.qf.listen;import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener;public class MyServletContextListener implements ServletContextListener {Overridepublic void contextInitialized(ServletContextEvent servletContextEvent) {ServletContext servletContext servletContextEvent.getServletContext();String info servletContext.getInitParameter(info);System.out.println(全局对象被创建了--info);}Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {System.out.println(全局对象被销毁了);} } 注1.生命周期为项目启动时创建服务器正常关闭时销毁。 经验应用场景 监听全局域对象的创建和销毁而全局域对象在项目启动时创建就意味着监听器里的初始化方法在项目启动时就会被调用所以我们可以把项目初始化的工作放在该方法里。在配置文件中context-param里设置初始数据建议放在最上面在监听器的初始化方法中可以用getInitParameter方法获取数据。 第一大类使用案例-统计在线人数 在全局域监听器中创建 servletContext.setAttribute(count,0); 在会话域监听器中统计 package com.qf.listen;import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener;public class MyHttpSessionListener implements HttpSessionListener {Overridepublic void sessionCreated(HttpSessionEvent httpSessionEvent) {HttpSession session httpSessionEvent.getSession();System.out.println(会话对象被创建了session.getId());ServletContext servletContext session.getServletContext();int count (int) servletContext.getAttribute(count);count;servletContext.setAttribute(count,count);}Overridepublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {System.out.println(会话对象被销毁了);HttpSession session httpSessionEvent.getSession();ServletContext servletContext session.getServletContext();int count (int) servletContext.getAttribute(count);count--;servletContext.setAttribute(count,count);} } 第二大类 请求属性监听器 MyServletRequestAttributeListener用注解配置: package com.qf.listen02;import javax.servlet.ServletRequestAttributeEvent; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.annotation.WebListener;WebListener public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {Overridepublic void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {String name servletRequestAttributeEvent.getName();Object value servletRequestAttributeEvent.getValue();System.out.println(请求域对象添加了属性name---value);}Overridepublic void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {String name servletRequestAttributeEvent.getName();Object value servletRequestAttributeEvent.getValue();System.out.println(请求域对象删除了属性name---value);}Overridepublic void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {String name servletRequestAttributeEvent.getName();Object value servletRequestAttributeEvent.getValue();//获取被替换的值System.out.println(请求域对象替换了属性name---value);} } page.jsp: %//操作请求域的属性request.setAttribute(msg,aaabbbccc);//添加属性request.setAttribute(msg,bbbcccddd);//替换属性request.removeAttribute(msg);//删除属性 %会话属性监听器 MyHttpSessionAttributeListener: package com.qf.listen02;import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent;public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {Overridepublic void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {String name httpSessionBindingEvent.getName();Object value httpSessionBindingEvent.getValue();System.out.println(会话域对象添加了属性);}Overridepublic void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {String name httpSessionBindingEvent.getName();Object value httpSessionBindingEvent.getValue();System.out.println(会话域对象删除了属性);}Overridepublic void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {String name httpSessionBindingEvent.getName();Object value httpSessionBindingEvent.getValue();System.out.println(会话域对象替换了属性);} } page02.jsp: %//操作会话域的属性session.setAttribute(msg,aaabbbccc);//添加属性session.setAttribute(msg,bbbcccddd);//替换属性session.removeAttribute(msg);//删除属性 %全局属性监听器 MyServletContextAttributeListener: package com.qf.listen02;import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener;public class MyServletContextAttributeListener implements ServletContextAttributeListener {Overridepublic void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {String name servletContextAttributeEvent.getName();Object value servletContextAttributeEvent.getValue();System.out.println(全局对象创建了属性--name--value);}Overridepublic void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {String name servletContextAttributeEvent.getName();Object value servletContextAttributeEvent.getValue();System.out.println(全局对象创建了属性--name--value);}Overridepublic void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {String name servletContextAttributeEvent.getName();Object value servletContextAttributeEvent.getValue();System.out.println(全局对象创建了属性--name--value);} } page03.jsp: %//操作全局域的属性application.setAttribute(msg,aaabbbccc);//添加属性application.setAttribute(msg,bbbcccddd);//替换属性application.removeAttribute(msg);//删除属性 %第三大类 HttpSessionBindingListener监听JavaBean对象在session中的绑定添加和解绑删除,即监听某一个具体的类对象第二大类是监听所有的类对象。 HttpSessionActivationListener:监听JavaBean对象在session中的钝化序列化和活化反序列化 User:实现HttpSessionBindingListenerHttpSessionActivationListenerSerializable package com.qf.listen03;import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionEvent; import java.io.Serializable;public class User implements HttpSessionBindingListener, HttpSessionActivationListener, Serializable {private String username;private String password;private String name;private String nickName;public User(String username, String password, String name, String nickName) {this.username username;this.password password;this.name name;this.nickName nickName;}public User() {}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}public String getName() {return name;}public void setName(String name) {this.name name;}public String getNickName() {return nickName;}public void setNickName(String nickName) {this.nickName nickName;}Overridepublic String toString() {return User{ username username \ , password password \ , name name \ , nickName nickName \ };}Overridepublic void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {System.out.println(this被session钝化了);}Overridepublic void sessionDidActivate(HttpSessionEvent httpSessionEvent) {System.out.println(this被session活化了);}Overridepublic void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {System.out.println(this绑定到session中了);}Overridepublic void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {System.out.println(this从session中解绑了);} } 在web里面创建META-INF文件夹写一个context.xml: ?xml version1.0 encodingUTF-8? ContextManager classNameorg.apache.catalina.session.PersistentManager maxIdleSwap1Store classNameorg.apache.catalina.session.FileStore directoryC:\\text//Manager /ContextServlet02: package com.qf.servlet;import com.qf.listen03.User;import javax.servlet.ServletException; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; WebServlet(/Servlet02) public class Servlet02 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(Servlet02接收到请求了...);HttpSession session request.getSession();//注意将user对象添加到session中可以叫做User对象绑定到session中 --- 绑定session.setAttribute(user,new User(1233211234567,123132,zs,fwkt));//注意将user对象从session中删除可以叫做User对象从session中解绑了 --- 解绑session.removeAttribute(user);} }Servlet03: package com.qf.servlet;import com.qf.listen03.User;import javax.servlet.ServletException; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;WebServlet(/Servlet03) public class Servlet03 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(Servlet03接收到请求了...);HttpSession session request.getSession();session.setAttribute(user,new User(1233211234567,123132,zs,fwkt));} }注意将User对象添加到session中可以叫做User对象绑定到session中 — 绑定 将User对象从session中删除可以叫做User对象从session中解绑 — 解绑 面试题session的钝化与活化 过滤器 简介 Filter过滤器拦截访问web资源的请求与响应操作 Servlet API中提供了Filter接口开发web应用时如果编写的Java类实现了这个接口则把这个Java类称之为过滤器。 创建与使用 场景welcome.html向Servlet01发送请求 package com.qf.servlet;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; WebServlet(/Servlet01.action) public class Servlet01 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding(UTF-8);response.setContentType(text/html;charsetUTF-8);System.out.println(Servlet收到请求了);} }过滤器 package com.qf.filter;import javax.servlet.*; import java.io.IOException;public class Filter01 implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println(Filter01 --- init());}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println(Filter01 --- doFilter() -- 放行前);filterChain.doFilter(servletRequest,servletResponse);System.out.println(Filter01 --- doFilter() -- 放行后);}Overridepublic void destroy() {System.out.println(Filter01 --- destroy());} } 配置文件 welcome-file-listwelcome-filewelcome.html/welcome-file/welcome-file-listfilterfilter-nameFilter01/filter-namefilter-classcom.qf.filter.Filter01/filter-class/filterfilter-mappingfilter-nameFilter01/filter-nameurl-pattern*.action/url-pattern/filter-mapping生命周期 创建项目启动时创建 – 构造方法、init 销毁项目正常关闭时销毁 – destroy 注意Filter对象是单例的。 当有多个过滤器时 配置文件 filterfilter-nameFilter01/filter-namefilter-classcom.qf.filter.Filter01/filter-class/filterfilter-mappingfilter-nameFilter01/filter-nameurl-pattern*.action/url-pattern/filter-mappingfilterfilter-nameFilter02/filter-namefilter-classcom.qf.filter.Filter01/filter-class/filterfilter-mappingfilter-nameFilter02/filter-nameurl-pattern*.action/url-pattern/filter-mappingfilterfilter-nameFilter03/filter-namefilter-classcom.qf.filter.Filter01/filter-class/filterfilter-mappingfilter-nameFilter03/filter-nameurl-pattern*.action/url-pattern/filter-mapping思考多个Filter的创建顺序多个Filter调用顺序 创建顺序无序底层是多线程抢资源。调用顺序为web.xml里的配置顺序推荐。如果是使用注解配置是按照类名字典排序。 案例1 编码过滤器 WEB-学生管理系统中写一个Encoderfilter类进行编码过滤就不必在servlet中设置了 配置文件标准写法要求匹配所有的action但是由于之前项目中servlet后没有加.action故此处偷懒直接写/* welcome-file-listwelcome-filewelcome.html/welcome-file/welcome-file-listfilterfilter-nameEncoderFilter/filter-namefilter-classcom.qf.filter.EncoderFilter/filter-class/filterfilter-mappingfilter-nameEncoderFilter/filter-nameurl-pattern/*/url-pattern/filter-mapping过滤器 package com.qf.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class EncoderFilter implements Filter {private String code;Overridepublic void init(FilterConfig filterConfig) throws ServletException {code filterConfig.getInitParameter(code);}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request (HttpServletRequest) servletRequest;HttpServletResponse response (HttpServletResponse) servletResponse;request.setCharacterEncoding(code);response.setContentType(text/html;charsetcode);filterChain.doFilter(request,response);}Overridepublic void destroy() {} } 案例2 登录权限过滤器 写一个LoginFilter。 配置文件 filterfilter-nameLoginFilter/filter-namefilter-classcom.qf.filter.LoginFilter/filter-class/filterfilter-mappingfilter-nameLoginFilter/filter-nameurl-pattern/*/url-pattern/filter-mappingLoginFilter: package com.qf.filter;import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;public class LoginFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request (HttpServletRequest) servletRequest;HttpServletResponse response (HttpServletResponse) servletResponse;String requestURI request.getRequestURI();System.out.println(requestURI); // StringBuffer requestURL request.getRequestURL(); // System.out.println(requestURL);HttpSession session request.getSession();String username (String) session.getAttribute(username);String role (String) session.getAttribute(role);String name (String) session.getAttribute(name);if(requestURI.equals(/Day37_war_exploded/register.jsp)||requestURI.equals(/Day37_war_exploded/login.jsp)||requestURI.equals(/Day37_war_exploded/CodeServlet)||requestURI.equals(/Day37_war_exploded/LoginServlet)||requestURI.equals(/Day37_war_exploded/)||requestURI.equals(/Day37_war_exploded/welcome.html)){filterChain.doFilter(request,response);}else{if(username!nullrole!nullname!null){if(student.equals(role) requestURI.contains(QueryAllStuServlet)) {response.sendRedirect(index.jsp);}else{filterChain.doFilter(request,response);}}}}Overridepublic void destroy() {} } 案例3 敏感词过滤器 场景在学生详情页面写一个建议跳转到proposal.jsp里面写一个表单提交到ProposalServlet %--Created by IntelliJ IDEA.User: GuDate: 2024-06-17Time: 17:37To change this template use File | Settings | File Templates. --% % page contentTypetext/html;charsetUTF-8 languagejava % html headtitleTitle/title /head bodyh2建议/h2form actionProposalServlet methodpost建议input typetext nameproposal/input typesubmit value提交/button typebutton οnclickfun01()返回/button/formscript typetext/javascriptfunction fun01(){window.location index.jsp;}/script /body /html ProposalServlet(输出建议) package com.qf.servlet;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; WebServlet(/ProposalServlet) public class ProposalServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String proposal (String) request.getParameter(proposal);response.getWriter().println(proposal);} }MyHttpServletRequestWrapper包装类继承HttpServletRequestWrapper类构造方法、重写getParameter方法 package com.qf.pojo;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper;public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {public MyHttpServletRequestWrapper(HttpServletRequest request) {super(request);}Overridepublic String getParameter(String name) {String parameter super.getParameter(name);if(parameter!null){parameter parameter.replaceAll(,lt;);parameter parameter.replaceAll(,gt;);parameter parameter.replaceAll(傻逼,**);}return parameter;} } SensitiveWordsFilter: package com.qf.filter;import com.qf.pojo.MyHttpServletRequestWrapper;import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException;public class SensitiveWordFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request (HttpServletRequest) servletRequest;MyHttpServletRequestWrapper requestWrapper new MyHttpServletRequestWrapper(request);filterChain.doFilter(requestWrapper,servletResponse);}Overridepublic void destroy() {} }
http://www.w-s-a.com/news/713005/

相关文章:

  • 适合推广的网站世界搜索引擎公司排名
  • 合肥网站建设费用ppt在哪个软件制作
  • 湖南省住房和城乡建设厅门户网站网站建设课程性质
  • 如何设计公司网站公司网站空间要多大
  • 建筑公司网站排名5G网站建设要多少个
  • seo怎样新建网站弹簧东莞网站建设
  • 在线做爰直播网站石家庄房产
  • 建筑网站哪里找拓者设计吧首页
  • 广州网站的建设wordpress注册数学验证码
  • 装修平台自己做网站有几个黄页名录网站开发
  • php网站的安全优势平面设计师培训
  • 乐清市网站建设设计重庆沙坪坝区
  • 什么是seo站内优化开发网页的工具有哪些
  • 文化类网站是不是休闲娱乐类网站青州市建设局网站
  • 网站的中英文切换代码做现货黄金网站
  • 万江区网站建设公司前端如何根据ui设计写页面
  • 宿迁公司做网站手机免费创建网站的软件
  • 免费可商用素材网站山东威海网站开发
  • 建设网站什么语言比较合适柳州建设网经济适用房
  • 企业网站的主要功能板块平台推广是做什么的
  • 网页网站自做全搞定西安建设工程信息网诚信平台
  • 网站vip怎么做建网站外包公司
  • 胶州建网站域名不备案可以正常使用吗
  • 网站建设客户开发方案软件工程师行业分析
  • 沈阳网站建设黑酷科技微信小程序怎么一键删除
  • 做网站产品搜索展示实现西安百度推广服务公司
  • 建立网站接受投注是什么意思一般使用的分辨率的显示密度是多少
  • 怎么建立一个网站开展业务网站建设人员的工资分配
  • 求职网站建设方案企业网站开发需求分析
  • 西安企业网站开发可以做哪些有趣的网站