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

建免费的网站全国最缺工100个职业排行出炉

建免费的网站,全国最缺工100个职业排行出炉,代加工订单,saas建站源码下载一、Servlet注解,简化配置 分析oa项目中的web.xml文件 现在只是一个单标的CRUD,没有复杂的业务逻辑,很简单的一丢丢功能。web.xml文件中就有如此多的配置信息。如果采用这种方式,对于一个大的项目来说,这样的话web.xml…

一、Servlet注解,简化配置

  • 分析oa项目中的web.xml文件

    • 现在只是一个单标的CRUD,没有复杂的业务逻辑,很简单的一丢丢功能。web.xml文件中就有如此多的配置信息。如果采用这种方式,对于一个大的项目来说,这样的话web.xml文件会非常庞大,有可能最终会达到几十兆。

    • 在web.xml文件中进行servlet信息的配置,显然开发效率比较低,每一个都需要配置一下。

    • 而且在web.xml文件中的配置是很少被修改的,所以这种配置信息能不能直接写到java类当中呢?可以的。

WebServlet 注解的源码:

// 该注解指定了此注解可以应用的目标元素类型为类、接口(包括注解类型)或枚举声明
@Target({ElementType.TYPE})
// 该注解指定了此注解的保留策略为在运行时保留,这样在运行时可以通过反射机制获取注解信息
@Retention(RetentionPolicy.RUNTIME)
// 该注解表示此注解会被包含在 JavaDoc 文档中
@Documented
// 定义一个名为 WebServlet 的注解
public @interface WebServlet {// 定义一个名为 name 的属性,默认值为空字符串// 该属性通常用于指定 Servlet 的名称String name() default "";// 定义一个名为 value 的属性,类型为字符串数组,默认值为空数组// 该属性通常用于指定 Servlet 的 URL 映射,是 urlPatterns 的简写形式String[] value() default {};// 定义一个名为 urlPatterns 的属性,类型为字符串数组,默认值为空数组// 该属性用于指定 Servlet 的 URL 映射String[] urlPatterns() default {};// 定义一个名为 loadOnStartup 的属性,默认值为 -1// 该属性指定 Servlet 的加载顺序,值为正数时表示在应用启动时加载,值越大越晚加载int loadOnStartup() default -1;// 定义一个名为 initParams 的属性,类型为 WebInitParam 数组,默认值为空数组// 该属性用于指定 Servlet 的初始化参数WebInitParam[] initParams() default {};// 定义一个名为 asyncSupported 的属性,默认值为 false// 该属性指定 Servlet 是否支持异步操作boolean asyncSupported() default false;// 定义一个名为 smallIcon 的属性,默认值为空字符串// 该属性用于指定 Servlet 的小图标路径String smallIcon() default "";// 定义一个名为 largeIcon 的属性,默认值为空字符串// 该属性用于指定 Servlet 的大图标路径String largeIcon() default "";// 定义一个名为 description 的属性,默认值为空字符串// 该属性用于指定 Servlet 的描述信息String description() default "";// 定义一个名为 displayName 的属性,默认值为空字符串// 该属性用于指定 Servlet 的显示名称String displayName() default "";
}
  • Servlet3.0版本之后,推出了各种Servlet基于注解式开发。优点是什么?

    • 开发效率高,不需要编写大量的配置信息。直接在java类上使用注解进行标注。

    • web.xml文件体积变小了。

  • 并不是说注解有了之后,web.xml文件就不需要了:

    • 有一些需要变化的信息,还是要配置到web.xml文件中。一般都是 注解+配置文件 的开发模式。

    • 一些不会经常变化修改的配置建议使用注解。一些可能会被修改的建议写到配置文件中。

我们的第一个注解:

jakarta.servlet.annotation.WebServlet
    • 在Servlet类上使用:@WebServlet,WebServlet注解中有哪些属性呢?

      • name属性:用来指定Servlet的名字。等同于:<servlet-name>

      • urlPatterns属性:用来指定Servlet的映射路径。可以指定多个字符串。<url-pattern>

      • loadOnStartUp属性:用来指定在服务器启动阶段是否加载该Servlet。等同于:<load-on-startup>

      • value属性:当注解的属性名是value的时候,使用注解的时候,value属性名是可以省略的。

      • 注意:不是必须将所有属性都写上,只需要提供需要的。(需要什么用什么。)

      • 注意:属性是一个数组,如果数组中只有一个元素,使用该注解的时候,属性值的大括号可以省略。

  • 注解对象的使用格式:

    • @注解名称(属性名=属性值, 属性名=属性值, 属性名=属性值....)

WebInitParam注解的源码

// 此注解可用于类、接口或枚举
@Target({ElementType.TYPE})
// 运行时可通过反射获取该注解信息
@Retention(RetentionPolicy.RUNTIME)
// 注解会包含在 JavaDoc 文档中
@Documented
/*** 为 Servlet 或过滤器定义初始化参数的注解*/
public @interface WebInitParam {// 初始化参数的名称,必填String name();// 初始化参数的值,必填String value();// 初始化参数的描述,可选,默认空字符串String description() default "";
}

1.游览器上打印这些数据

HelloServlet类

package oop1;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;@WebServlet(name = "hello",urlPatterns = {"/hello1", "/hello2", "/hello3"},//loadOnStartup = 1,initParams = {@WebInitParam(name="username", value="root"), @WebInitParam(name="password", value="123")})
public class HelloServlet extends HttpServlet {// 无参数构造方法public HelloServlet() {System.out.println("无参数构造方法执行,HelloServlet加载完成");}/*@WebServletprivate String name;*/@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();// 获取Servlet NameString servletName = getServletName();out.print("servlet name = " + servletName + "<br>");// 获取servlet pathString servletPath = request.getServletPath();out.print("servlet path = " + servletPath + "<br>");// 获取初始化参数Enumeration<String> names = getInitParameterNames();while (names.hasMoreElements()) {String name = names.nextElement();String value = getInitParameter(name);out.print(name + "=" + value + "<br>");}}
}

2.@WebServlet的简化写法

package oop1;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
import java.io.PrintWriter;//@WebServlet(urlPatterns = {"/welcome1", "/welcome2"})
// 注意:当注解的属性是一个数组,并且数组中只有一个元素,大括号可以省略。
//@WebServlet(urlPatterns = "/welcome")
// 这个value属性和urlPatterns属性一致,都是用来指定Servlet的映射路径的。
//@WebServlet(value = {"/welcome1", "/welcome2"})
// 如果注解的属性名是value的话,属性名也是可以省略的。
//@WebServlet(value = "/welcome1")
//@WebServlet({"/wel", "/abc", "/def"})
@WebServlet("/wel")
public class WelcomeServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.print("欢迎学习Servlet。");}
}

3.使用反射机制将类上面的注解进行解析

package oop1;import jakarta.servlet.annotation.WebServlet;public class ReflectAnnotation {public static void main(String[] args) throws Exception{// 使用反射机制将类上面的注解进行解析。// 获取类Class对象Class<?> welcomeServletClass = Class.forName("oop1.WelcomeServlet");// 获取这个类上面的注解对象// 先判断这个类上面有没有这个注解对象,如果有这个注解对象,就获取该注解对象。//boolean annotationPresent = welcomeServletClass.isAnnotationPresent(WebServlet.class);//System.out.println(annotationPresent);if (welcomeServletClass.isAnnotationPresent(WebServlet.class)) {// 获取这个类上面的注解对象WebServlet webServletAnnotation = welcomeServletClass.getAnnotation(WebServlet.class);// 获取注解的value属性值。String[] value = webServletAnnotation.value();for (int i = 0; i < value.length; i++) {System.out.println(value[i]);}}}
}

二、使用模板方法设计模式优化oa项目

  • 上面的注解解决了配置文件的问题。但是现在的oa项目仍然存在一个比较臃肿的问题。

    • 一个单标的CRUD,就写了6个Servlet。如果一个复杂的业务系统,这种开发方式,显然会导致类爆炸。(类的数量太大。)

    • 怎么解决这个类爆炸问题?可以使用模板方法设计模式。

  • 怎么解决类爆炸问题?

    • 以前的设计是一个请求一个Servlet类。1000个请求对应1000个Servlet类。导致类爆炸。

    • 可以这样做:一个请求对应一个方法。一个业务对应一个Servlet类。

    • 处理部门相关业务的对应一个DeptServlet。处理用户相关业务的对应一个UserServlet。处理银行卡卡片业务对应一个CardServlet。

add.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>新增部门</title></head><body><h1>新增部门</h1><hr ><form action="/oa/dept/save" method="post">部门编号<input type="text" name="deptno"/><br>部门名称<input type="text" name="dname"/><br>部门位置<input type="text" name="loc"/><br><input type="submit" value="保存"/><br></form></body>
</html>

edit.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>修改部门</title></head><body><h1>修改部门</h1><hr ><form action="list.html" method="get">部门编号<input type="text" name="deptno" value="20" readonly /><br>部门名称<input type="text" name="dname" value="销售部"/><br>部门位置<input type="text" name="loc" value="北京"/><br><input type="submit" value="修改"/><br></form></body>
</html>

error.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>error</title>
</head>
<body>
<h1>操作失败,<a href="javascript:void(0)" onclick="window.history.back()">返回</a></h1>
</body>
</html>

index.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>欢迎使用OA系统</title></head><body><!--前端超链接发送请求的时候,请求路径以“/”开始,并且要带着项目名--><a href="/oa/dept/list">查看部门列表</a></body>
</html>

DBUtil

package oop1.utils;import java.sql.*;
import java.util.ResourceBundle;/*** JDBC的工具类*/
public class DBUtil {// 静态变量:在类加载时执行。// 并且是有顺序的。自上而下的顺序。// 属性资源文件绑定private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");// 根据属性配置文件key获取valueprivate static String driver = bundle.getString("driver");private static String url = bundle.getString("url");private static String user = bundle.getString("user");private static String password = bundle.getString("password");static {// 注册驱动(注册驱动只需要注册一次,放在静态代码块当中。DBUtil类加载的时候执行。)try {// "com.mysql.jdbc.Driver" 是连接数据库的驱动,不能写死。因为以后可能还会连接Oracle数据库。// 如果连接oracle数据库的时候,还需要修改java代码,显然违背了OCP开闭原则。// OCP开闭原则:对扩展开放,对修改关闭。(什么是符合OCP呢?在进行功能扩展的时候,不需要修改java源代码。)//Class.forName("com.mysql.jdbc.Driver");Class.forName(driver);} catch (ClassNotFoundException e) {e.printStackTrace();}}/*** 获取数据库连接对象* @return conn 连接对象* @throws SQLException*/public static Connection getConnection() throws SQLException {// 获取连接Connection conn = DriverManager.getConnection(url, user, password);return conn;}/*** 释放资源* @param conn 连接对象* @param ps 数据库操作对象* @param rs 结果集对象*/public static void close(Connection conn, Statement ps, ResultSet rs){if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (ps != null) {try {ps.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}

jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
user=root
password=abc123

DeptServlet类

package oop1.web.action;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import oop1.utils.DBUtil;import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;// 模板类
@WebServlet({"/dept/list", "/dept/save", "/dept/edit", "/dept/detail", "/dept/delete", "/dept/modify"})
// 模糊匹配
// 只要请求路径是以"/dept"开始的,都走这个Servlet。
//@WebServlet("/dept/*")
public class DeptServlet extends HttpServlet {// 模板方法// 重写service方法(并没有重写doGet或者doPost)@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取servlet pathString servletPath = request.getServletPath();if("/dept/list".equals(servletPath)){doList(request, response);} else if("/dept/save".equals(servletPath)){doSave(request, response);} else if("/dept/edit".equals(servletPath)){doEdit(request, response);} else if("/dept/detail".equals(servletPath)){doDetail(request, response);} else if("/dept/delete".equals(servletPath)){doDel(request, response);} else if("/dept/modify".equals(servletPath)){doModify(request, response);}}private void doList(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取应用的根路径String contextPath = request.getContextPath();// 设置响应的内容类型以及字符集。防止中文乱码问题。response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.print("<!DOCTYPE html>");out.print("<html>");out.print("	<head>");out.print("		<meta charset='utf-8'>");out.print("		<title>部门列表页面</title>");out.print("<script type='text/javascript'>");out.print("    function del(dno){");out.print("        if(window.confirm('亲,删了不可恢复哦!')){");out.print("            document.location.href = '"+contextPath+"/dept/delete?deptno=' + dno");out.print("        }");out.print("    }");out.print("</script>");out.print("	</head>");out.print("	<body>");out.print("		<h1 align='center'>部门列表</h1>");out.print("		<hr >");out.print("		<table border='1px' align='center' width='50%'>");out.print("			<tr>");out.print("				<th>序号</th>");out.print("				<th>部门编号</th>");out.print("				<th>部门名称</th>");out.print("				<th>操作</th>");out.print("			</tr>");/*上面一部分是死的*/// 连接数据库,查询所有的部门Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {// 获取连接conn = DBUtil.getConnection();// 获取预编译的数据库操作对象String sql = "select deptno as a,dname,loc from dept";ps = conn.prepareStatement(sql);// 执行SQL语句rs = ps.executeQuery();// 处理结果集int i = 0;while(rs.next()){String deptno = rs.getString("a");String dname = rs.getString("dname");String loc = rs.getString("loc");out.print("			<tr>");out.print("				<td>"+(++i)+"</td>");out.print("				<td>"+deptno+"</td>");out.print("				<td>"+dname+"</td>");out.print("				<td>");out.print("					<a href='javascript:void(0)' onclick='del("+deptno+")'>删除</a>");out.print("					<a href='"+contextPath+"/dept/edit?deptno="+deptno+"'>修改</a>");out.print("					<a href='"+contextPath+"/dept/detail?fdsafdsas="+deptno+"'>详情</a>");out.print("				</td>");out.print("			</tr>");}} catch (SQLException e) {e.printStackTrace();} finally {// 释放资源DBUtil.close(conn, ps, rs);}/*下面一部分是死的*/out.print("		</table>");out.print("		<hr >");out.print("		<a href='"+contextPath+"/add.html'>新增部门</a>");out.print("	</body>");out.print("</html>");}private void doSave(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取部门的信息// 注意乱码问题(Tomcat10不会出现这个问题)request.setCharacterEncoding("UTF-8");String deptno = request.getParameter("deptno");String dname = request.getParameter("dname");String loc = request.getParameter("loc");// 连接数据库执行insert语句Connection conn = null;PreparedStatement ps = null;int count = 0;try {conn = DBUtil.getConnection();String sql = "insert into dept(deptno, dname, loc) values(?,?,?)";ps = conn.prepareStatement(sql);ps.setString(1, deptno);ps.setString(2, dname);ps.setString(3, loc);count = ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(conn, ps, null);}if (count == 1) {// 保存成功跳转到列表页面// 转发是一次请求。//request.getRequestDispatcher("/dept/list").forward(request, response);// 这里最好使用重定向(浏览器会发一次全新的请求。)// 浏览器在地址栏上发送请求,这个请求是get请求。response.sendRedirect(request.getContextPath() + "/dept/list");}else{// 保存失败跳转到错误页面//request.getRequestDispatcher("/error.html").forward(request, response);// 这里也建议使用重定向。response.sendRedirect(request.getContextPath() + "/error.html");}}private void doEdit(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取应用的根路径。String contextPath = request.getContextPath();response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.print("<!DOCTYPE html>");out.print("<html>");out.print("	<head>");out.print("		<meta charset='utf-8'>");out.print("		<title>修改部门</title>");out.print("	</head>");out.print("	<body>");out.print("		<h1>修改部门</h1>");out.print("		<hr >");out.print("		<form action='"+contextPath+"/dept/modify' method='post'>");// 获取部门编号String deptno = request.getParameter("deptno");// 连接数据库,根据部门编号查询部门的信息。Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = DBUtil.getConnection();String sql = "select dname, loc as location from dept where deptno = ?";ps = conn.prepareStatement(sql);ps.setString(1, deptno);rs = ps.executeQuery();// 这个结果集中只有一条记录。if(rs.next()){String dname = rs.getString("dname");String location = rs.getString("location"); // 参数"location"是sql语句查询结果列的列名。// 输出动态网页。out.print("                部门编号<input type='text' name='deptno' value='"+deptno+"' readonly /><br>");out.print("                部门名称<input type='text' name='dname' value='"+dname+"'/><br>");out.print("                部门位置<input type='text' name='loc' value='"+location+"'/><br>");}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(conn, ps, rs);}out.print("			<input type='submit' value='修改'/><br>");out.print("		</form>");out.print("	</body>");out.print("</html>");}private void doDetail(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.print("<!DOCTYPE html>");out.print("<html>");out.print("	<head>");out.print("		<meta charset='utf-8'>");out.print("		<title>部门详情</title>");out.print("	</head>");out.print("	<body>");out.print("		<h1>部门详情</h1>");out.print("		<hr >");// 获取部门编号// /oa/dept/detail?fdsafdsas=30// 虽然是提交的30,但是服务器获取的是"30"这个字符串。String deptno = request.getParameter("fdsafdsas");// 连接数据库,根据部门编号查询部门信息。Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = DBUtil.getConnection();String sql = "select dname,loc from dept where deptno = ?";ps = conn.prepareStatement(sql);ps.setString(1, deptno);rs = ps.executeQuery();// 这个结果集一定只有一条记录。if(rs.next()){String dname = rs.getString("dname");String loc = rs.getString("loc");out.print("部门编号:"+deptno+" <br>");out.print("部门名称:"+dname+"<br>");out.print("部门位置:"+loc+"<br>");}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(conn, ps, rs);}out.print("		<input type='button' value='后退' onclick='window.history.back()'/>");out.print("	</body>");out.print("</html>");}private void doDel(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 根据部门编号,删除部门。// 获取部门编号String deptno = request.getParameter("deptno");// 连接数据库删除数据Connection conn = null;PreparedStatement ps = null;int count = 0;try {conn = DBUtil.getConnection();// 开启事务(自动提交机制关闭)conn.setAutoCommit(false);String sql = "delete from dept where deptno = ?";ps = conn.prepareStatement(sql);ps.setString(1, deptno);// 返回值是:影响了数据库表当中多少条记录。count = ps.executeUpdate();// 事务提交conn.commit();} catch (SQLException e) {// 遇到异常要回滚if (conn != null) {try {conn.rollback();} catch (SQLException ex) {ex.printStackTrace();}}e.printStackTrace();} finally {DBUtil.close(conn, ps, null);}// 判断删除成功了还是失败了。if (count == 1) {//删除成功//仍然跳转到部门列表页面//部门列表页面的显示需要执行另一个Servlet。怎么办?转发。//request.getRequestDispatcher("/dept/list").forward(request, response);response.sendRedirect(request.getContextPath() + "/dept/list");}else{// 删除失败//request.getRequestDispatcher("/error.html").forward(request, response);response.sendRedirect(request.getContextPath() + "/error.html");}}private void doModify(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 解决请求体的中文乱码问题。request.setCharacterEncoding("UTF-8");// 获取表单中的数据String deptno = request.getParameter("deptno");String dname = request.getParameter("dname");String loc = request.getParameter("loc");// 连接数据库执行更新语句Connection conn = null;PreparedStatement ps = null;int count = 0;try {conn = DBUtil.getConnection();String sql = "update dept set dname = ?, loc = ? where deptno = ?";ps = conn.prepareStatement(sql);ps.setString(1, dname);ps.setString(2, loc);ps.setString(3, deptno);count = ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(conn, ps, null);}if (count == 1) {// 更新成功// 跳转到部门列表页面(部门列表页面是通过Java程序动态生成的,所以还需要再次执行另一个Servlet)//request.getRequestDispatcher("/dept/list").forward(request, response);response.sendRedirect(request.getContextPath() + "/dept/list");}else{// 更新失败//request.getRequestDispatcher("/error.html").forward(request, response);response.sendRedirect(request.getContextPath() + "/error.html");}}}

http://www.dtcms.com/wzjs/823125.html

相关文章:

  • 网站设计建设公司教程广州网站手机建设公司
  • 做网站用什么字体字号微信制作小程序的软件
  • 百度微建站wordpress管理员账号
  • 网站首页为什么不收录施工企业负责人每月带班时间不少于
  • 做长图的网站羽毛球赛事2022直播
  • 成都品牌营销策划有限公司网站指定关键词优化
  • 网站淘宝客怎么做的wordpress视频下载
  • 网站建设可用性邵阳红网站
  • 彩票网站维护需要几天买程序的网站
  • 投票活动网站怎么做太原小程序制作
  • 自己做的网站怎么被搜录正规网站建设价格费用
  • 百度推广会帮你做网站不创意网红
  • 阿里云可以做电商网站吗设计展厅的公司
  • 建站时长是什么原因造成的图书拍卖网站开发遇到的问题
  • 河北做it的网站dede网站后缀乱码
  • 网站健设推广产品多少钱网站和服务器的关系
  • 盐城做网站推广电话小型局域网组建方案
  • 福建设计院网站哈尔滨公司网站
  • 怎样利用云盘做电影网站怎样制作企业的网站
  • 帮人盖章网站备案授权书网站建设培训证书
  • 东莞网站建设完整网上注册平台怎么注册
  • 博客网站做外贸可以吗手机网站设计公司皆选亿企邦
  • 2w网站建设发展环境镇江哪里做网站
  • 新网站怎么做才能可以在百度上搜索到原创文章网站
  • 织梦文章类网站模板外贸开发模板网站模板
  • 巴中住房建设部网站北京移动端网站价格
  • 沧州网站优化价格计算机科学与技术网站
  • 广告公司网站设计策划wordpress用php版本
  • 口碑好的徐州网站建设wordpress 主机 设置ftp
  • 新手做网站需要什么台州网站设计 解放路