1.12 网 站 发 布
如今有很多网络用户以自己的计算机作为服务器,发布网站到Internet,这也是一个不错的选择,为网站的更新和维护提供了很大的便利。
在发布Java Web程序到Internet之前,需具备如下前提条件(假设使用的是Tomcat服务器):
拥有一台可连接到Internet的计算机,并且是固定IP。
拥有一个域名。
在可连接到Internet的计算机上要有Java Web程序的运行环境,即已经成功安装了JDK和Tomcat服务器。
拥有一个可运行的Java Web应用程序。
拥有了上述条件,就可以将已经拥有的Java Web程序发布到Internet了。发布步骤如下:
(1)申请一个域名,例如www.yxq.com。
(2)将域名的A记录的IP指向自己的计算机的IP。
(3)在本地计算机中创建一个目录用来存放Java Web程序,如D:\JSPWeb。
(4)将Java Web程序复制到D:\JSPWeb目录下,可对其重命名,如命名为01_CityInfo。
(5)将Tomcat服务器端口改为80。修改方法为:打开Tomcat安装目录下conf目录中的server.xml文件,并找到以下配置代码。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改<Connector>元素中port属性的值为80。
(6)建立虚拟主机,主机名为申请的域名。创建方法为:打开Tomcat安装目录下conf目录中的server.xml文件,找到<Host>元素并进行如下配置。
<Host name="www.yxq.com" appBase="D:/JSPWeb"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/city" docBase="01_CityInfo" debug='0' reaload="true"/>
</Host>
<Host>元素用来创建主机,name属性指定了主机名(域名),appBase属性指定了Java Web应用程序存放在本地计算机中的位置。<Context>元素用来配置主机的Web应用程序,path属性指定了访问主机中某个Web应用的路径,docBase属性指定了相对于D:/JSPWeb目录下的Java Web应用程序路径。所以,若访问www.yxq.com/city路径,既可访问D:/JSPWeb目录下的01_CityInfoWeb应用程序,也可以将path属性设置为“/”,这样直接访问www.yxq.com即可访问01_CityInfoWeb应用程序。
(7)访问站点。启动Tomcat服务器,在浏览器地址栏中输入“https://www.yxq.com/city”,访问发布的Java Web应用程序。
也可通过该方法将网站发布到局域网内,只不过在<Host>元素中name属性指定的是计算机名称,并且该计算机名称不能包含空格或“.”等非法字符,否则,局域网内的其他计算机将不能访问发布的网站。
1.13 开发技巧与难点分析
1.13.1 实现页面中的超链接
虽然在应用Struts框架开发Web应用时,推荐使用Struts中提供的标签,但有些时候不妨灵活地使用原始的HTML语言中的一些标识。例如,在页面中实现一个超链接,链接请求的资源为welcome.jsp页面,若使用Struts 2.0的a标签实现:
<s2:a href="<s2:url value='/welcome.jsp'/>">转发</s2:a>
则上述代码将生成如下HTML代码:
<a href="<s2:url value='/welcome.jsp'/>">转发</a>
所以该超链接请求的资源为<s2:url value='/welcome.jsp'/>,很显然不是预期的效果。可以写为如下形式:
<s2:a href="welcome.jsp">转发</s2:a>
但是,如果超链接请求的资源是动态改变的,或者传递的参数也是动态改变的,这时可以使用HTML语言中的标识来实现:
<a href="<s2:url value="/welcome.jsp"/>">转发</a>
<a href="welcome.jsp?name=<s2:url value='yxq'/>">传参</a>
则上述代码将生成如下HTML代码:
<a href="welcome.jsp">转发</a>
<a href="welcome.jsp?name=yxq">传参</a>
1.13.2 Struts 2.0中的中文乱码问题
为在Struts 2.0中解决中文乱码问题,可在struts.properties文件中进行如下配置。
struts.i18n.encoding=gb2312
struts.i18n.encoding用来设置Web应用默认的编码,gb2312则指定了默认的编码。
该方法可以解决提交表单后出现的中文乱码问题。此时,表单的method属性值必须为post,若使用Struts 2.0中的form标签实现的表单,可省略method属性,默认值为post;若是通过原始的HTML语言的form标识实现的表单,则需要设置method属性,并赋值为post。
如果某个超链接传递的参数的值是中文字符,则在Action业务控制器中获取该参数值后,必须进行如下转码操作,否则获取的值为乱码。
String sqlvalue=request.getParameter("sqlvalue"); //获取超链接传递的参数
sqlvalue=new String(sqlvalue.getBytes("ISO-8859-1"),"gb2312"); //进行转码操作
1.14 Struts 2.0框架搭建与介绍
1.14.1 搭建Struts 2.0框架
本系统使用的Struts 2.0框架为Struts 2.0.11版本,读者可到网站https://struts.apache.org/download.cgi # struts2011下载Full Distribution,Full Distribution为Struts 2.0.11的完整版本,其中包含了Struts 2.0的类库、示例应用、说明文档和源代码等资源。解压下载后的文件的目录结构如图1.59所示。
下面介绍Struts 2.0框架的搭建。
1.导入Struts 2.0类包文件
通常情况下,如果将如图1.59所示的lib目录下的commons-logging- 1.0.4.jar、freemarker-2.3.8.jar、ognl-2.6.11.jar、struts2-core-2.0.11.jar和xwork-2.0.4.jar包文件复制到Web应用中的WEB-INF/lib目录下,就可应用Struts 2.0开发项目了。如果想使用Struts 2.0中的更多功能,将其他的JAR包文件复制到WEB-INF/lib目录下即可。
图1.59 Struts 2.0框架目录结构
2.配置Web应用的web.xml文件
打开Web应用中WEB-INF目录下的web.xml文件,并进行如下配置。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="https://java.sun.com/xml/ns/j2ee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/j2ee
https://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>struts2</filter-name> <!-- 命名Struts 2.0核心类 -->
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> <!-- 指定Struts 2.0核心类 -->
</filter>
<filter-mapping> <!-- 配置核心类处理的请求 -->
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern> <!-- 指定处理用户所有请求 -->
</filter-mapping>
</web-app>
经过如上操作就完成了Struts 2.0框架的搭建。
Struts 2.0中提供的标签并没有像Struts之前的版本那样进行分类,但在页面中的使用方法是相同的,都需要通过taglib指令来引入,并指定一个前缀。Struts 2.0的标签描述文件存放在struts2-core-2.0.11.jar包中的META-INF目录下,文件名为struts-tags.tld。以下为struts-tags.tld描述文件中的代码片段:
<taglib>
<tlib-version>2.2.3</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>s</short-name>
<uri>/struts-tags</uri>
<display-name>"Struts Tags"</display-name>
……
</taglib>
代码中的<uri>元素将该标签描述文件与/struts-tags名称进行了映射,所以在JSP页面中可直接通过如下代码引入Struts 2.0标签。
<%@ taglib prefix="s2" uri="/struts-tags" %>
当然也可以将标签复制到其他位置,然后在web.xml文件中指定。例如,将struts-tags.tld文件复制到Web应用中的WEB-INF/tld目录下,并在web.xml文件中进行如下配置。
<taglib>
<taglib-uri>struts2</taglib-uri>
<taglib-location>/WEB-INF/tld/struts-tags.tld</taglib-location>
</taglib>
然后在JSP页面中通过如下代码引入Struts 2.0标签:
<%@ taglib prefix="s2" uri="struts2" %>
1.14.2 Struts 2.0框架介绍
Struts 2.0与Struts1.0存在很大的差别,因为Struts 2.0是以WebWork为核心,可以说是WebWork框架的升级版本,因此具有WebWork开发经验的读者,会更容易学习Struts 2.0框架。
1.控制器
Struts 2.0中的控制器分为核心控制器和业务控制器(用户控制器),其中业务控制器是用户创建的Action类。下面介绍这两种控制器。
核心控制器:FilterDispatcher。
FilterDispatcher类存在于org.apache.struts2.dispatcher包下,继承了javax.servlet.Filter接口。在应用的web.xml文件中需要配置该控制器,用来接收用户的所有请求,FilterDispatcher会判断请求是否为*.action模式,如果匹配,则FilterDispatcher将请求转发给Struts 2.0框架进行处理。在web.xml文件中对FilterDispatcher的配置可查看1.14.1节中的介绍。
业务控制器。
由用户创建的Action类实例,充当着Struts 2.0中的业务控制器,也可称为用户控制器。创建Action类时,通常使其继承Struts 2.0包中的com.opensymphony.xwork2.ActionSupport类。在Action类中可实现execute()方法,当有请求访问该Action类时,execute()方法会被调用来处理请求,这与Struts之前的版本中Action的处理是相同的。
在Struts之前的版本中,若Action类继承自org.apache.struts.actions.DispatchAction父类,那么该Action会根据用户请求调用相应的自定义方法来处理请求,不必实现execute()方法。同样,在Struts 2.0中要实现这样的功能,可通过两种方法,即在配置文件中的指明调用方法和在请求路径中的指明调用方法。具体的使用方法在前面已经作了讲解,读者可查看1.7.3节“列表显示信息的实现过程”中的 内容。
同之前的版本一样,Struts 2.0也需要在配置文件中对Action进行配置。该配置主要就是将用户请求与业务控制器进行关联,然后指定请求处理结束后返回的视图资源。例如:
<!-- 若请求路径中包含“userLogin.action”,则转发给LoginAction业务控制器 -->
<action name="userLogin" class="com.yxq.action.LoginAction">
<result>/welcome.jsp</result> <!-- 登录成功后,转发到welcome.jsp页面 -->
<result name="loginError">/login.jsp</result> <!-- 登录失败后,转发到login.jsp页面 -->
</action>
在Struts 2.0中可使用拦截器处理请求。在一些拦截器中通过com.opensymphony.xwork2.Action- Context类将请求、会话与Map对象进行了映射。在开发程序时,若仅仅是对请求或会话进行存取数据的操作,则可使创建的Action控制器继承相应的接口,在拦截器中来判断该Action控制器是哪个接口的实例,根据判断,生成一个与请求进行映射的Map对象或与会话进行映射的Map对象。在用户的Action控制器中,对这些Map对象进行数据存取操作,即可实现对请求或会话的数据存取操作。
Struts 2.0中实现该功能的拦截器为ServletConfigInterceptor,它存放在struts2-core-2.0.11.jar中的org.apache.struts2.interceptor包下,其部分代码如下:
public String intercept(ActionInvocation invocation) throws Exception {
final Object action = invocation.getAction(); //获取请求要访问的Action控制器
final ActionContext context = invocation.getInvocationContext(); //获取Action上下文
if (action instanceof ParameterAware) { //如果控制器是ParameterAware类实例
((ParameterAware) action).setParameters(context.getParameters());
}
if (action instanceof RequestAware) { //如果控制器是RequestAware类实例
((RequestAware) action).setRequest((Map) context.get("request"));
}
if (action instanceof SessionAware) { //如果控制器是SessionAware类实例
((SessionAware) action).setSession(context.getSession());
}
……
return invocation.invoke(); //调用Action控制器
}