首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 操作系统-> Linux教程
最简单的Struts程序-JSP教程,资料/其它
作者:网友供稿 点击:865
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
[目标]

实现一个最简单的struts程序。程序包括一个输入页和输出页,输入页。

对于学习程序设计,我们已习惯于从hello程序开始,实践证明,这是一个最有效的入门方法。下面就着手设计我们的第一个struts程序----hello程序。hello程序的目标是实现从一个输入jsp页面中的输入框输入一个“hello”单词,在另一个输出jsp页面中显示“hello”一词。根据struts框架的要求,这个hello程序将包含输入jsp文件、输出jsp文件、action文件、formaction文件及配置文件。也就是说,这个hello程序是一个完整的struts程序,它可直接在tomact、resin等服务器上运行。





[效果]

输入页面:


输出页面:








[背景知识]

以前使用servlet开发应用系统的人深深感受到在java代码中嵌入大量html代码是一件非常痛苦的事,于是sun推出了jsp,解决了java代码中嵌入html代码的问题。但是很快程序员们就知道,用jsp“在html代码中嵌入大量java代码”跟“在java代码中嵌入大量html代码”是一样的非常痛。jsp是这样,asp也是这样。于是,craig r. mcclanahan借用mvc的思想,把java web应用程序的java和html分离开放在不同的文件中,分成了三部分,也就是struts;后来,微软也学会了这种分离方法,但微软懒一些,只分成了两部分,也就是asp.net。

struts (org.apache.struts)是一个开放源代码的web应用框架,基于mvc设计模式,使用servlet和jsp api建立,可以用来构建复杂的web应用。它允许我们分解一个应用程序的商业逻辑、控制逻辑和表现逻辑的代码,使它的重用性和维护性更好。struts框架是jakarta工程的一部分,由apache软件基金会管理。struts可以从http://jakarta.apache.org/ struts站点下载。

struts框架提供以下服务。

作为mvc结构中的controller的servlet.

jsp里用于bean管理、html和javascript生成、模板处理和流程控制的jsp标签库。

用于国际化消息的框架。国际化你的web应用,意味着你的web应用在使用时可以让用户以喜爱的语言显示。这意味着你需要创建一个应用资源文件,包含每种语言的信息。

一个jdbc的实现来定义数据源和数据库连接池。

一个通用的的错误和异常处理机制,包括从一个应用程序资源文件读取错误信息。

xml语法分析。

文件上载工具。

注册机制。

一个基于struts的应用程序的表示层(view)使用struts标签库(taglibs)构建。来自客户的请求被传递给叫actionservlet的servlet,它作为controller.使用了struts的应用程序,所有需要通过框架的请求都通过actionservlet传递。这个actionservlet把数据从请求传递到actionform javabean。

actionform是代表从一个表单view组件输入数据的javabean。这些表单由jsp用struts html标签库产生。这个beam由 actionservlet生成,带request参数,它还请求actionform来验证用户提交数据的合法性。

actionservlet通过定义一组actionmapping来配置。一个actionmapping是一个对象,它将请求中的url映射到由应用程序开发者提供的处理请求的组件。actionservlet和actionmapping的配置在xml配置文件中完成。

专用的应用程序用于处理请求的组件叫action类。在mvc结构中,它们代表模型。它们可能用于验证用户输入的合法性,假如在信息处理过程中出现了应用程序错误,action类可以创建一个error对象的实例,然后保存庆http request对象中。如果在action类中的逻辑成功地被招待类给controller传递一个actionforward对象,代表所需的描绘响应的jsp。actionforward有两种:专门转发给特定的action类或全局转发(任何一个action类可以把这些actionforwards转给controller)。







[步骤]



1、打开visual struts开发环境:

(1)把文件拷贝到本地硬盘的一个目录下,例如

   f:\javawebstudio\

(2) 运行bin目录下的javawebstudio.exe文件(同时自动在桌面建立一个快捷方式,第二次启动时,只需点击桌面的快捷方式即可),出现如下启动界面:


另外,第一次运行javawebstudio,会提示是否要自动配置环境变量,建议选择自动配置。



2、建立一个“空的struts普通模板”应用程序:

选择菜单“文件”—“新建”—“新建项目”,弹出新建项目对话框,如图3-1所示:




在对话框中选择“空的struts普通用模板”,在项目名称中输入“simple”,package (包名)和位置(项目的路径)采用默认的值就行,当然也可以根据需要改变。最后点击“确定”按钮完成新项目的建立。




从文件管理器中可看出simple项目的文件结构如下:


simple

+------config

+------lib

+------src

+------web

-------build.xml

-------hello.prj

在simple项目根目录下包含四个子目录和两个文件,这是jspstudio项目的标准结构,最好不要改变它们默认的名称,否则会出现问题。



3、利用struts文件向导建立新的应用:

在jspstudio文件管理器内点击鼠标右键,在弹出的菜单中选择“struts文件向导”进入struts文件向导对话框,也可以选择菜单“文件”—“新建”—“ struts文件向导”进入struts文件向导对话框。如图3-3所示:




在struts文件向导对话框jsp文件标签下的文件名输入栏中输入“hellword”文件名,其它文件采用默认的设置,点击“确定”按钮完成在struts文件向导。

刷新jspstudio文件管理器,这时发现web目录下自动生成了两个文件,分别是hellword.jsp和hellword.jsp,前者是输入jsp文件,后者是输出jsp文件;src\emptyprj目录下自动生成了两个文件,分别是hellword action.java和hellword form.java,前者是action文件,后者formaction文件。






4、编译、启动服务器:


点击工具条上的编译按钮或选择菜单“生成”—“编译”开始项目的编译。编译过程和结果在输出栏中显示出来,内容如下:

c:\documents and settings\administrator\桌面>f:

f:\>cd f:\javawebstudio\javawebstudioworkdir\simple

f:\javawebstudio\javawebstudioworkdir\simple>ant -buildfile build.xml

buildfile: build.xml

prepare:

[mkdir] created dir: f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple

[copy] copying 2 files to f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple

[mkdir] created dir: f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple\web-inf

[copy] copying 6 files to f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple\web-inf

[mkdir] created dir: f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple\web-inf\classes

[copy] copying 5 files to f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple\web-inf\classes

[mkdir] created dir: f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple\web-inf\lib

[copy] copying 18 files to f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple\web-inf\lib

[mkdir] created dir: f:\javawebstudio\javawebstudioworkdir\wars

compile:

[javac] compiling 3 source files to

f:\javawebstudio\jakarta-tomcat-5.0.24\webapps\simple\web-inf\classes

dist:

[jar] building jar: f:\javawebstudio\javawebstudioworkdir\wars\simple.war

build successful

total time: 5 seconds

上述输出表明利用ant 编译build.xml所设置的项目已成功。把编译结果拷贝到tomcat服务器webapps目录下,并生成打包文件simple.war。



5、启动服务器:

点击工具条上的启动服务器按钮或选择菜单“运行”—“ 启动服务器”启动服务器jakarta-tomcat服务器。内容如下:






6、运行:

展开文件管理器simple项目下web目录,可见到helloword.jap和hellowordout.jsp文件,通过双击打开helloword.jap文件,如图所示。编辑窗口分上下两部分,上部分是源程序编辑,下部分是可视化编辑,与dreamweaver mx编辑窗口相似。




点击工具条上的运行按钮或选择菜单“运行”—“ 运行(web浏览)”这时打开显示出helloword.jsp的运行结果。在运行结果页面中的输入框中输入“hello word”,点击“提交”按钮,这时转发到hellowordout.jsp文件,hellowordout.jsp页面中输出“hello word”一词。




生成的源代码如下:

<html><head><title></title>

<meta http-equiv=content-type content="text/html; charset=gb2312">

</head>

<body bgcolor=white>

<base href="http://localhost:8080/simple/helloword.jsp"> <form name="hellowordform" method="post" action="/simple/hellowordaction.do;jsessionid=cffac422c4a779419348832d588ca5be">

<input type="text" name="mybeanvariable1" value=""> <input type="submit" value="提交"> <input type="reset" value="重写">

</form>

</body>

</html>




生成的源代码如下:

<html><head><title></title>

<base href="http://localhost:8080/simple/hellowordout.jsp">

</head>

<body bgcolor="white">

hello word

</body>

</html>



[项目文件结构]




config目录下包含了所有的配置文件和struts标签的描述文件,例如web.xml、struts-config.xml、struts-bean.tld、struts-html.tld、struts-logic.tld和struts-template.tld等文件。

lib包含了struts库文件和带用其它库文件,例如struts.jar、struts-legacy.jar、commons-lang.jar和xerces.jar等文件。

src目录下包含了java原文件和资源文件,例如applicationresources.properties和applicationresources_ch.properties资源文件,前者是英语资源文件,后者是中文资源文件。新建时这个目录里还有一个子目录“emptyprj”,这个名称与建立项目时输入的package名称是一至的。emptyprj目录下有“filters”、“jdbc”两个子目录,前者是过滤器目录,是中文解决方案,详细分析请看后面的有关滤器程序设计、中文解决方案章节,后者是数据库连接池文件,详细分析请看后面的struts数据库应用程序设计章节。

web目录下包含了jsp、html等web文件和web文件用到的图片文件。新建时这个目录是空的。

build.xml文件是编译是所需的配置文件,由于jspstudio采用的是ant编译器,所以这个文件是jspstudio项目中必不可少的,它是ant标准的配置文件,所有的项目目录结构也符合ant编译器的要求,可见jspstudio项目与ant具有非常好的兼容性,这也是jspstudio的优点之一。

hello.prj文件是项目文件,xml结构,内容如下:

<projectname>simple</projectname>

<projecttype>struts</projecttype>

<title>这是一个建立空的struts普通模板</title>

<package>emptyprj</package>

<typepath>\jave web 项目\空的struts普通模板</typepath>

<projectpath>f:\javawebstudio\javawebstudioworkdir\simple</projectpath>

<projectname>标签内是项目名称;<projecttype>标签内是项目的类型,这个标签的内容最好不要改变;<title>标签内是项目的简单说明,可根据需要填写;<package>标签内是默认的package名称;<typepath>标签内是项目模板的相对路径;<projectpath>标签内是项目保存的绝对路径。







[关键技术]



struts使用mvc结构;图2.1所示的逻辑图描述了框架的高层结构。

我们现在讨论图中的每个元素。

一个基于struts的应用程序的表示层(view)使用struts标签库(taglibs)构建。来自客户的请求被传递给叫actionservlet的servlet,它作为controller.使用了struts的应用程序,所有需要通过框架的请求都通过actionservlet传递。这个actionservlet把数据从请求传递到actionform javabean。

actionmapping

actionform (模型的数据)

action (模型的业逻辑)

发送

actionservlet (controller)

jsp (view)

taglib (view)

使用

实例化

调用

使用

使用


 




















 
图2.1

actionform是代表从一个表单view组件输入数据的javabean。这些表单由jsp用struts html标签库产生。这个beam由 actionservlet生成,带request参数,它还请求actionform来验证用户提交数据的合法性。

actionservlet通过定义一组actionmapping来配置。一个actionmapping是一个对象,它将请求中的url映射到由应用程序开发者提供的处理请求的组件。actionservlet和actionmapping的配置在xml配置文件中完成。

专用的应用程序用于处理请求的组件叫action类。在mvc结构中,它们代表模型。它们可能用于验证用户输入的合法性,假如在信息处理过程中出现了应用程序错误,action类可以创建一个error对象的实例,然后保存庆http request对象中。如果在action类中的逻辑成功地被招待类给controller传递一个actionforward对象,代表所需的描绘响应的jsp。actionforward有两种:专门转发给特定的action类或全局转发(任何一个action类可以把这些actionforwards转给controller)。





本例主要文件之间的关系:

输入页面:

helloword.jsp

actionform (模型的数据)

hellowordform.java

actionservlet (controller)



通过struts-config.xml配置实现



actionmapping



输入页面:

hellowordout.jsp

action (模型的业逻辑)

hellowordaction.java






[关键源代码分析]

4.3.1 输入jsp页面文件

输入jsp页面文件名是hello.jsp,主要实现一个带有文本框的表单,文件代码如下:

<%@ page contenttype="text/html;charset=gb2312" language="java" %>

<%@ taglib uri="/web-inf/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/web-inf/struts-html.tld" prefix="html" %>

<%@ taglib uri="/web-inf/struts-logic.tld" prefix="logic" %>

<%@ taglib uri="/web-inf/struts-template.tld" prefix="template" %>

<html:html>

<head>

<title></title>

<html:base/>

</head>

<body bgcolor="white">

<html:form action="/helloaction.do" method="post">

<html:text property="mybeanvariable1" />

<html:submit value="提交" />

<html:reset value="重写" />

</html:form>

</body>

</html:html>



首先是把本页定义为支持中文显示,中文编码采用gb2312格式,程序语言为java:

<%@ page contenttype="text/html;charset=gb2312" language="java" %>

接着定义支持四种struts标签bean、html、logic和template,在该文件中没用到的标签可以去掉相应的定义,如果在文件中还需要用到自定义标签,也需要在这里加入相应的定义:

<%@ taglib uri="/web-inf/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/web-inf/struts-html.tld" prefix="html" %>

<%@ taglib uri="/web-inf/struts-logic.tld" prefix="logic" %>

<%@ taglib uri="/web-inf/struts-template.tld" prefix="template" %>

<html:html>就不用说了。<html:base/>标签对应html的<base>标签,用来设定测览器中文件的绝对路径,然后在文件中只需写下文件的相对位置,在测览器中测览的时候这些位置会自动附在绝对路径后面,成为完整的路径。在文档中所有相对地址形式的url是相对于这里定义的utrl而言的。一篇文档中的<base>标记不能多于一个,必须放于<head>标签内,并且应该在任何包含url地址的语句之前定义。<html:form>这里用了黑体字,表示是要重点讲解的地方。

<html:form action="/helloaction.do" method="post">

<html:text property="mybeanvariable1" />

<html:submit value="提交" />

<html:reset value="重写" />

</html:form>

<html:form>标签定义了一个表单,提交时的目标url是“/helloaction.do”,方法是“post”,post方法是将用户在表单中填写的数据包含在表单的主体中,一起传送到服务器上的处理程序中,该万法没有字符的限制,它包含了iso10646的字符集,是一种邮寄的万式,在测览器的地址栏不显示提交的信息,这种万式传送的数据是没有限制。当然也可以选择get方法,get方法是将表单内容附加在url地址后面,所以对提交信息的长度进行了限制,最多不可以超过8192个字符,如果信息大长,将被截去,从而导致意想不到的结果,而且不能传送非ascii码的字符。表单内包含一个文本输入框<html:text>,它的值与bean中属性为"mybeanvariable1"的变量相对应,如果结mybeanvariable1付了初值,则在启动这个页面时文本框中就显示默认的mybeanvariable1初值。另外表单内还包含了两个最常见的提交按钮<html:submit value="提交" />和重写按钮<html:reset value="重写" />。



4.3.2 输出jsp页面文件

输出jsp页面文件名是helloout.jsp,主要实现输入文件提交的文本框的值,文件代码如下:

<%@ page contenttype="text/html;charset=gb2312" language="java" %>

<%@ taglib uri="/web-inf/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/web-inf/struts-html.tld" prefix="html" %>

<%@ taglib uri="/web-inf/struts-logic.tld" prefix="logic" %>

<html:html>

<head>

<title></title>

<html:base/>

</head>

<body bgcolor="white">

<html:html>

<head>

<title></title>

<html:base/>

</head>

<body bgcolor="white">

<bean:write name="helloform" property="mybeanvariable1" />

</body>

</html:html>

</body>

</html:html>

输出文件与前面输入文件唯一不同的是把<html:form>标签变成了<bean:write>标签:

<bean:write name="helloform" property="mybeanvariable1" />

<bean:write>标签实现bean属性值的输出,其中name保存bean名,这里是“helloform”,从后面的配置文件可以看出,它对应的类是helloform类;property保存属性名,这里是“mybeanvariable1”,与输入文件的文本框取的属性名一至。



4.3.3 actionform bean文件

hello程序的actionform bean文件实现只包含一个变量的bean,文件名是helloform.java,文件代码如下:

package emptyprj;

import javax.servlet.http.httpservletrequest;

import org.apache.struts.action.actionerror;

import org.apache.struts.action.actionerrors;

import org.apache.struts.action.actionform;

import org.apache.struts.action.actionmapping;

public final class hellowordform extends actionform

{

private string mybeanvariable1;

public string getmybeanvariable1()

{

return (this.mybeanvariable1);

}

public void setmybeanvariable1(string mybeanvariable1)

{

this.mybeanvariable1=mybeanvariable1;

}

}

首先是定义package名:

package emptyprj;

这是选用了jspstudio默认的package名emptyprj,需注意的是package名要与目录名对应。接着引入了actionform bean设计中常用的五个类httpservletrequest、actionerror、actionerrors、actionform和actionmapping,这是jspstudio自动加入的,实际上helloform类只用于actionform类,其它部分可以删除,但这里保留它以方便以后扩展程序时用。

import javax.servlet.http.httpservletrequest;

import org.apache.struts.action.actionerror;

import org.apache.struts.action.actionerrors;

import org.apache.struts.action.actionform;

import org.apache.struts.action.actionmapping;

接下来就是定义了helloform、一个参数mybeanvariable1和它对应的get()、set()函数,这与普通bean定义的方法一模一样。



4.3.4 action文件

hello程序的action文件实现对输入文件提交的表单的处理,文件名是helloaction.java,文件代码如下:

package emptyprj;

import java.lang.reflect.invocationtargetexception;

import java.util.locale;

import javax.servlet.servletexception;

import javax.servlet.http.httpsession;

import javax.servlet.http.httpservletrequest;

import javax.servlet.http.httpservletresponse;

import org.apache.commons.beanutils.propertyutils;

import org.apache.commons.logging.log;

import org.apache.commons.logging.logfactory;

import org.apache.struts.action.action;

import org.apache.struts.action.actionerror;

import org.apache.struts.action.actionerrors;

import org.apache.struts.action.actionform;

import org.apache.struts.action.actionforward;

import org.apache.struts.action.actionmapping;

import org.apache.struts.action.actionservlet;

import org.apache.struts.util.moduleexception;

import org.apache.struts.util.messageresources;



public final class hellowordaction extends action

{

// 变量定义:

private log log = logfactory.getlog("org.apache.struts.webapp.example");

//函数定义:

public actionforward execute(actionmapping mapping,

actionform form,

httpservletrequest request,

httpservletresponse response)

throws exception

{

// extract attributes and parameters we will need

locale locale = getlocale(request);

messageresources messages = getresources(request);

httpsession session = request.getsession();

hellowordform myform = (hellowordform) form;

string variable1= myform.getmybeanvariable1();

try

{

if(variable1.trim().equals(""))

{

return new actionforward(mapping.getinput());

}

//其它代码

return (mapping.findforward("success"));

}

catch (exception e)

{

//log.error("出错", e);

//log.trace("出错");

throw new runtimeexception(e.getmessage());

}

}

}

首先定义处理函数execute(),可以理解为当hello输入文件表单提交到服务器的actionservlet,由actionservlet调用action的execute()函数实现商业逻辑处理,处理完成后把结果转发到输出文件中。execute()函数定义一个helloform实例“myform”,并从提交的输入actionform对象实例form中读取数据,把mybeanvariable1变量的值赋给新的字符串变量variable1:

helloform myform = (helloform) form;

string variable1= myform.getmybeanvariable1();

接下来是出错处理,try语句用于组合一个引起异常的代码块,它使我们告诉java要注意有可能出现异常的代码段;catch:一旦掷出一个异常,需要捕获住这个异常,catch语句使程序员定义一个捕获;finally:在try/catch块结尾,程序可能需要确保一个代码块不管是否掷出了异常,总是被执行,例如不管发生什么,我们可能都需要确保关闭特定的文件; exceptlon:一种用于存放在代码中发现的关于一个"exception"或"error"的信息的类;throws:当某些事需要关注时,我们"掷出"一个异常。这个异常被我们创建的一段处理异常的特殊代码"抓住"。涣句话说,通过掷出一个异常,我们告诉代码:出错啦,需要调用一些特殊的逻辑去处理问题。下面完它的完整结束:

try

{

//正常代码

}

catch (exception e)

{

//出错处理代码

throw new runtimeexception(e.getmessage());

}

finally

{

//最后都必需进行的处理代码

}



在try块中我们进行的变量variable1是否为空的判断,如果为空就转发到输入页,否则转发到定义为success的输出页:

if(variable1.trim().equals(""))

{

return new actionforward(mapping.getinput());

}

//其它代码

return (mapping.findforward("success"));

mapping.getinput()函数用于获取输入页的url值,这个值与配置文件struts-config.xml中<action>项的input属性值相对应。



4.3.5 struts程序配置

<?xml version="1.0" encoding="iso-8859-1" ?>

<!doctype struts-config public

"-//apache software foundation//dtd struts configuration 1.0//en"

"http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">

<struts-config>

<form-beans>

<form-bean name="hellowordform"

type="emptyprj.hellowordform" />

</form-beans>

<action-mappings>

<action path="/hellowordaction"

type="emptyprj.hellowordaction"
name="hellowordform"

scope="session"

input="/helloword.jsp">

<forward name="success" path="/hellowordout.jsp" />

</action>

</action-mappings>

</struts-config>





文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·最简单的Struts程序-JSP教程,资料/其它
·利用激光供电的光电电流互感器
·java到structs-JSP教程,Java技巧及代码
·鼠标样式,整体背景图,滚动条的效果(网页效果)-ASP教程,ASP应用
·ASP中正则表达式的应用-ASP教程,正则表达式
·XML应用-利用XML 与XSL-.NET教程,XML应用
·.net 下用javascript调用webservice-.NET教程,Web Service开发
·Asp无组件上传进度条解决方案-ASP教程,组件开发
·破译动网验证码的简单方法-.NET教程,评论及其它
·linux系统文件命令精通指南(上)
最新文章
·mashups+ajax打造全新web开发_ajax教程
·windows vista系统中写字板应用全攻略_windows vista
·adsense单价持续低迷的解读_网赚技巧
·google反作弊小组成员专访_站长访谈
·端午议话:谈网站的特色_站长心得
·浅谈我的十点论坛管理经验_站长心得
·如何针对msn的onpage进行网页优化_站长心得
·用google 搜索框黏住易变的访问者_google推广
·google关键词广告每次点击付费(ppc)术语表_google推广
·确保万无一失的google 关键词广告公式_google推广
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭