文章转自:http://blog.csdn.net/webrobot/article/details/7839344
一、compass实现搜索
1、配置1.1、加入如下jar包。
1.2、将compass与spring集成,让compass使用spring的事务,配置文件如下:
bean.xml文件中加入如下内容
<bean id="compass" class="org.compass.spring.LocalCompassBean">
<!-- 指定映射类方式 -->
<property name="classMappings">
<list>
<value>com.nbchina.bean.article.Article</value>
<value>com.nbchina.bean.article.ArticleClass</value>
</list>
</property>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">file://e:/index</prop>
<prop key="compass.engine.highlighter.default.formatter.simple.pre"><![CDATA[<font color='red'>]]></prop>
<prop key="compass.engine.highlighter.default.formatter.simple.post"><![CDATA[</font>]]></prop>
<prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop>
</props>
</property>
<property name="transactionManager" ref="transactionManager" />
</bean>
<!-- CompassGps为CompassGpsDevice提供Compass对象,他们一起为程序提供索引的实时更新 -->
<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
<property name="compass" ref="compass" />
<property name="gpsDevices">
<list>
<bean class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
<property name="gpsDevice">
<!-- 为gpsDevice属性注入针对JPA的GPS驱动 -->
<bean class="org.compass.gps.device.jpa.JpaGpsDevice">
<property name="name" value="jpaDevice" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="injectEntityLifecycleListener" value="true"/>
</bean>
</property>
</bean>
</list>
</property>
</bean>
Article实体内容如下
@Entity @Searchable //通过这个注解,指明该类跟lucene中的document映射
public class Article {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@SearchableId
private Integer id;
@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name="acid")
@SearchableComponent
private ArticleClass ac;
//@SearchableComponent代表还要跟其他类关联
//boost=2数字越大级别越高,代表标题检索到的排序在前。默认为1.
//index=Index.NO代表不参与索引
//store=Store.YES代表储存
//name="titleName" 有些字段和关联的其他表字段相同,那么可以重命名。
@Column(length=80,nullable=false)
@SearchableProperty(boost=2,store=Store.YES, name="titleName")
private String title;
@Column(length=255)
private String titleIntact;
@Column(length=10)
private String titleFontColor;
@Column(length=255)
private String linkURL;
@Column(length=255)
private String keyword;
@Column(length=255)
@SearchableProperty(index=Index.NO,store=Store.YES)
private String intro;
@Column(nullable=false)
private Integer hits = 1;
@Temporal(TemporalType.DATE) @Column(nullable=false)
@SearchableProperty(index=Index.NO,store=Store.YES,format="yyyy-MM-dd")
private Date updateTime = new Date();
@Column(nullable=false)
private Boolean onTop = false;
@Column(nullable=false)
private Boolean elite = false;
@Column(nullable=false)
private Boolean hot = false;
@Column(nullable=false)
private Integer status = 0;
@Column(nullable=false)
private Integer deleted = 0;
@Column(length=80)
private String editor = "admin";
@Column(length=80)
private String author = "佚名";
@Column(length=80)
private String copyFrom;
@Lob @Column(nullable=false)
@SearchableProperty(store=Store.YES)
private String content;
@Column(nullable=true)
private Integer includeImage = 0;
@Lob
private String uploadFiles;
@Column(length=255)
private String includeImageURL;
@Column(length=255)
private String voiceURL;
}
@Entity @Searchable(root=false)
public class ArticleClass implements Serializable{
//@Searchable(root=false)代表不是搜索的根类,是Article的配角,关联的类而已。
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@SearchableProperty(index=Index.NO, store=Store.YES)
private Integer id;
@Column(length=36,nullable=false)
@SearchableProperty(index=Index.NO, store=Store.YES)
private String name;
@Column(length=200)
private String note;
@Column(nullable=false)
private Boolean visible=true;
@Column(nullable=false)
private Integer orderId=0;
@Column(length=255)
private String imageURL;
@Column(length=10)
private String level;
@OneToMany(cascade={CascadeType.REFRESH,CascadeType.REMOVE},mappedBy="parent")
private Set<ArticleClass> childs = new HashSet<ArticleClass>();
@ManyToOne(cascade=CascadeType.REFRESH)
@JoinColumn(name="parentid")
private ArticleClass parent;
@OneToMany(mappedBy="ac", cascade=CascadeType.REMOVE)
@SearchableReference //表示引用article
private Set<Article> articles = new HashSet<Article>();
}
建立ArticleSearchServiceBean. Java
@Service @Transactional
public class ArticleSearchServiceBean extends CompassDaoSupport implements ArticleSearchService {
@Resource
public void setSessionFactory(Compass compass){
super.setCompass(compass);
}
public QueryResult<Article> search(String key, int startIndex, int maxResult) {
return this.getCompassTemplate().execute(new ArticleResultCallback(key, startIndex, maxResult));
}
}
建立ArticleResultCallback.java
- public class ArticleResultCallback implements CompassCallback<QueryResult<Article>> {
- private String key;
- private int startIndex;
- private int maxResult;
- public ProductResultCallback(String key, int startIndex, int maxResult) {
- this.key = key;
- this.startIndex = startIndex;
- this.maxResult = maxResult;
- }
- public QueryResult<Article> doInCompass(CompassSession session) throws CompassException {
- List<Article> articles = new ArrayList<Article>();
- CompassHits hits = session.find(key);
- int lastIndex = startIndex + maxResult - 1;
- if(lastIndex>(hits.length()-1)) lastIndex = hits.length()-1;
- for(int i=startIndex; i<=lastIndex; i++){
- Article article = (Article) hits.data(i);
- if(hits.highlighter(i).fragment("title")!=null){//处理高亮显示
- article.setTitle(hits.highlighter(i).fragment("title"));
- }
- articles.add(article);
- }
- QueryResult<Article> qr = new QueryResult<Article>();
- qr.setResultlist(articles);
- qr.setTotalrecord(hits.length());//设置查询到的总记录数
- return qr;
- }
- }
- QueryResult<Article> qr = articleSearchService.search("关键字", pageView.getFirstResult(), pageView.getMaxresult());
- pageView.setQueryResult(qr);
order实体内加入
/* 锁定该订单的员工,如果该值不为null,即订单被锁定 */
private String employee;
OrderServiceBean内加入
public Order getLockOrder(String orderid, String employee){
em.createQuery("update Order o set o.employee=?1 where o.orderid=?2 and o.employee is null")
.setParameter(1, employee).setParameter(2, orderid).executeUpdate();
em.flush();
return this.find(orderid);
}
public void unLock(String orderid){
em.createQuery("update Order o set o.employee=?1 where o.orderid=?2")
.setParameter(1, null).setParameter(2, orderid).executeUpdate();
}
action内加入、
if(!order.getEmployee().equals(username)){
request.setAttribute("message", "该订单已被"+ order.getEmployee() + "锁定");
return mapping.findForward("message");
}
jsp内判断
<c:if test="${empty entry.employee || entry.employee==employee.username}"><a href="">载入订单</a></c:if>
<c:if test="${!empty entry.employee && entry.employee!=employee.username}">被${entry.employee}锁定</c:if>
三、Velocity 模版静态化
1、Velocity配置
如下代码加入到系统初始化代码块中
try{
Properties prop = new Properties();
prop.put("runtime.log", config.getServletContext().getRealPath("/WEB-INF/Log/velocity.log"));
prop.put("file.resource.loader.path", config.getServletContext().getRealPath("/WEB-INF/VM"));
prop.put("input.encoding", "UTF-8");
prop.put("output.encoding", "UTF-8");
Velocity.init(prop);
System.out.println("Velocity Initialized");
}catch( Exception e ){
System.out.println("VSelocity error");
e.printStackTrace();
}
引入Velocity1.6 jar 包
2、实例
WebRoot-WEB-INF-VM目录下建立mailContent.vm
文件内容如下
<html>
<head>
<title>测试</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
尊敬的客户:${userName}
</body>
</html>
使用代码如下
Template template = Velocity.getTemplate("mailContent.vm","UTF-8");
VelocityContext context = new VelocityContext();
context.put("userName", "测试名");
StringWriter writer = new StringWriter();
template.merge(context, writer);
writer.flush();
String mailContent = writer.toString();
EmailSender.send(entry.getEmail(), "测试", mailContent, "text/html");
三、Velocity脚本语法摘要
1. 变量
(1)变量的定义:
#set($name = "hello") 说明:velocity中变量是弱类型的。
当使用#set 指令时,括在双引号中的字面字符串将解析和重新解释,如下所示:
#set($directoryRoot = "www" )
#set($templateName = "index.vm" )
#set($template = "$directoryRoot/$templateName" )
$template
输出将会是:www/index.vm
注:在velocity中使用$2.5这样的货币标识是没有问题得的,因为velocity中的变量总是以一个大写或者小写的字母开始的。
(2)变量规范的写法
${name} ,也可以写成:$name。提倡用前面的写法。
例如:你希望通过一个变量$vice来动态的组织一个字符串。
Jack is a $vicemaniac.
本来变量是$vice现在却变成了$vicemaniac,这样Veloctiy就不知道您到底要什么了。所以,应该使用规范的格式书写 : Jack is a ${vice}maniac
现在Velocity知道变量是$vice而不是$vicemaniac。
注意:当引用属性的时候不能加{}
(3)变量的赋值:
$name="hello"
赋值的左边必须是一个变量或者是属性引用。右边可以是下面六种类型之一:
变量引用,字面字符串,属性引用,方法引用,字面数字,数组列表。
下面的例子演示了上述的每种类型:
#set( $monkey = $bill ) ## variable reference
#set( $monkey.Friend = "monica" ) ## string
#set( $monkey.Blame = $whitehouse.Leak ) ## property reference
#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference
#set( $monkey.Number = 123 ) ##number
#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList
注意:①如果上述例子中的右值是null, 则左值不会被赋值,也就是说会保留以前的值。
②velocity模板中未被定义的变量将被认为是一个字符串。例如:
#set($foo = "gibbous")
$moon = $foo
输出结果为:
$moon = gibbous
③velocity模板中不会将reference解释为对象的实例变量。例如:$foo.Name将被解释为Foo对象的getName()方法,而不是Foo对象的Name实例变量。例如:
$foo.getBar() 等同于$foo.Bar ;
$data.getUser("jon") 等同于$data.User("jon") ;
data.getRequest().getServerName() 等同于
$data.Request.ServerName等同于${data.Request.ServerName}
2. 循环
#foreach ($element in $list)
This is $element.
$velocityCount
#end
例子:
#set( $list = ["pine", "oak", "maple"])
#foreach ($element in $list)
$velocityCount
This is $element.<br>
#end
输出的结果为:
1 This is pine.
2 This is oak.
3 This is maple.
每次循环$list中的一个值都会赋给$element变量。
$list可以是一个Vector、Hashtable或者Array。分配给$element的值是一个java对象,并且可以通过变量被引用。例如:如果$element t是一个java的Product类,并且这个产品的名字可以通过调用他的getName()方法得到。
#foreach ( $key in $list.keySet())
Key: $key -> Value: $list.get($key) <br>
#end
提示:velocity中大小写敏感。
Velocity还特别提供了得到循环次数的方法,$velocityCount变量的名字是Velocity默认的名字。
例子:
First example:
#foreach ( $foo in [1..5] )
$foo
#end
Second example:
#foreach ( $bar in [2..-2] )
$bar
#end
Third example:
#set ( $arr = [0..1] )
#foreach ( $i in $arr )
$i
#end
上面三个例子的输出结果为:
First example:
1 2 3 4 5
Second example:
2 1 0 -1 -2
Third example:
0 1
3. 条件语句
#if (condition)
#elseif (condition)
#else
#end
4. 语句的嵌套
#foreach ($element in $list)
## inner foreach 内循环
#foreach ($element in $list)
This is $element. $velocityCount <br>inner<br>
#end
## inner foreach 内循环结束
## outer foreach
This is $element.
$velocityCount <br>outer<br>
#end
语句中也可以嵌套其他的语句,如#if…#else…#end等。
5. 注释
(1)单行注释:
## This is a single line comment.
(2)多行注释:
#*
Thus begins a multi-line comment. Online visitors won’t
see this text because the Velocity Templating Engine will
ignore it.
*#
(3)文档格式:
#**
This is a VTL comment block and
may be used to store such information
as the document author and versioning
information:
@version 1.1
@author xiao
*#
6. 关系和逻辑操作符
Velocity 也具有逻辑AND, OR 和 NOT 操作符。
如
## example for AND
#if($foo && $bar)
<strong> This AND that</strong>
#end
例子中#if() 指令仅在$foo 和$bar 斗为真的时候才为真。如果$foo 为假,则表达式也为假;并且 $bar 将不被求值。如果 $foo 为真,Velocity 模板引擎将继续检查$bar的值,如果 $bar 为真,则整个表达式为真。并且输出This AND that 。如果 $bar 为假,将没有输出因为整个表达式为假。
7.Velocity 中的宏
Velocity中的宏我们可以理解为函数。
①宏的定义
#macro(宏的名称 $参数1 $参数2 …)
语句体(即函数体)
#end
②宏的调用
#宏的名称($参数1 $参数2 …)
说明:参数之间用空格隔开。
8.#stop
停止执行模板引擎并返回,把它应用于debug是很有帮助的。
9.#include与#parse
#include和#parse的作用都是引入本地文件, 为了安全的原因,被引入的本地文件只能在TEMPLATE_ROOT目录下。
区别:
(1) 与#include不同的是,#parse只能指定单个对象。而#include可以有多个
如果您需要引入多个文件,可以用逗号分隔就行:
#include ("one.gif", "two.txt", "three.htm" )
在括号内可以是文件名,但是更多的时候是使用变量的:
#include ( “greetings.txt”, $seasonalstock )
(2) #include被引入文件的内容将不会通过模板引擎解析;
而#parse引入的文件内容Velocity将解析其中的velocity语法并移交给模板,意思就是说相当与把引入的文件copy到文件中。
#parse是可以递归调用的,例如:如果dofoo.vm包含如下行:
Count down.<br>
#set ($count = 8)
#parse ("parsefoo.vm")
<br>All done with dofoo.vm!
那么在parsefoo.vm模板中,你可以包含如下VTL:
$count
#set($count = $count - 1)
#if ( $count > 0 )<br>
#parse( "parsefoo.vm" )
#else
<br>All done with parsefoo.vm!
#end的显示结果为:
Count down.
8
7
6
5
4
3
2
1
0
All done with parsefoo.vm!
All done with dofoo.vm!
注意:在vm中使用#parse来嵌套另外一个vm时的变量共享问题。如:
->a.vm 里嵌套 b.vm;
->a.vm 里定义了变量 $param;
->b.vm 里可以直接使用$param,无任何限制。
但需要特别注意的是,如果b.vm里同时定义有变量$param,则b.vm里将使用b.vm里定义的值。
10.转义字符'\'的使用
如果reference被定义,两个’\’意味着输出一个’\’,如果未被定义,刚按原样输出。如:
#set($email = "foo" )
$email
\$email
\\$email
\\\$email
输出:
foo
$email
\foo
\$email
如果$email 未定义
$email
\$email
\\$email
\\\$email
输出:
$email
\$email
\\$email
\\$email
11.内置对象
Velocity内置了一些对象,在vm模版里可以直接调用,列举如下:
$request、$response、$session,另外,模板内还可以使用 $msg内的消息工具访问 Struts 的国际化资源,达到简便实现国际化的方法。
12. 数组访问
对数组的访问在Velocity中存在问题,因为Velocity只能访问对象的方法,而数组又是一个特殊的Array,所以虽然数组可以进行循环列举,但却不能定位访问特定位置的元素,如 strs[2],数组对固定位置元素的访问调用了Array的反射方法get(Object array, int index),而Velocity没能提供这样的访问,所以数组要么改成List等其他类容器的方式来包装,要么就通过公用Util类的方式来提供,传入数组对象和要访问的位置参数,从而达到返回所需值的目的。
四、OSCache缓存
1、hibernate与OSCache对比
hibernate 二级缓存仅仅针对实体进行缓存。
oscache 针对整体或者局部进行缓存。速度更快,更全面。
http://java.net/downloads/oscache/ 下载路径
2、配置
第二步:把oscache安装目录下的/etc/oscache.properties 文件放入 /WEB-INF/classes目录.开发阶段,我们可以把该文件放置在src目录.
下载路径:http://www.opensymphony.com/oscache/
oscache.jar
\lib\commons-logging.jar
3、实例
使用OSCache作页面局部缓存
我们使用Oscache的标签<oscache></oscache>来进行页面的局部缓存.使用方法如下:
<%@taglib uri="http://www.opensymphony.com/oscache" prefix=“oscache"%>
<oscache:cache>
<%=new Date() %>
</oscache:cache>
缓存的key将以请求的URI+查询字串组成,如果你访问/oscache/index.jsp?name=ttt和/oscache/index.jsp?name=ppp将得到两份缓存。缓存默认存放在application范围,缓存时间默认为3600秒,即1小时.
<oscache:cache key=“name”>
name=${param.name}
</oscache:cache>
这时候缓存将以name为key,不再是请求的URI+查询字串组成,所以如果你访问/oscache/index.jsp?name=ttt和/oscache/index.jsp?name=ppp将得到一份缓存。
<oscache:cache key="name" scope="session">
name=${param.name}
</oscache:cache>
缓存范围设置为session,这时候缓存保存在用户的session中,如果用户的把浏览器关闭,再重新打开一个新浏览器,原来缓存的内容将不存在。
<oscache:cache key="name" time="10">
name=${param.name}
</oscache:cache>
上面设置了缓存的时间为10秒,超过10秒后,缓存的内容将失掉。
<oscache:cache key="name" time="60" refresh="${param.refresh}">
name=${param.name}
</oscache:cache>
refresh为true将会导致缓存的内容过期而被清除,简单地说,该属性为true用于清除缓存。
人为管理缓存<flush />标签:
<oscache:flush scope="application" />
清除application范围内的所有缓存
<oscache:flush scope="session" key="foobar" />
清除session范围内的key为foobar的缓存。
<oscache:flush scope="application" group="currencyData" />
清除application范围内组名为currencyData内的所有缓存。
在局部缓存,显示动态人名的时候。可以这么做。
你好<SCRIPT Languge=JavaScript src="welcome.js"></SCRIPT>,欢迎访问。
welcome.js代码如下。
function readCookieByName(name){
var nameOfCookie = name + "=";
var x = 0;
while ( x <= document.cookie.length ){
var y = (x+nameOfCookie.length);
if ( document.cookie.substring( x, y ) == nameOfCookie ) {
if ( (endOfCookie=document.cookie.indexOf( ";", y )) == -1 )
endOfCookie = document.cookie.length;
return document.cookie.substring( y, endOfCookie );
}
x = document.cookie.indexOf( " ", x ) + 1;
if ( x == 0 ) break;
}
return "";
}
function readWelcomeMsg(){
try{
var msg = readCookieByName("realName");
if(msg!=""){
return decodeURI(msg);
}else{
msg = readCookieByName("userName");
if(msg!="") return msg;
}
} catch(e){
;
}
return "";
}
document.write(readWelcomeMsg());
使用OSCache作页面全局缓存
页面全局缓存将使用Filter实现:
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>7200</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>application</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
这个filter应该放在最上面,这样才会第一个通过它,如果存在缓存,就不需要访问后面,直接返回
缓存的key将以请求的URI+查询字串组成,如果你访问/oscache/index.jsp?name=ttt和/oscache/index.jsp?name=ppp将得到两份缓存。缓存是在初次访问页面时进行的,后续的请求将会返回缓存中的内容。缓存中存放的内容为页面返回给用户的html源代码。
oscache.properties文件设置如下:
指定是否使用内存缓存,默认值为true,即使用内存缓存。
cache.capacity
指定缓存的容量,默认的容量是无限的。我们可以为它设置缓存数量,如:
cache.capacity=100000
如果我们要使用硬盘缓存,可以这样设置:
cache.memory=false
cache.path=d:\\cache (指定,缓存保存的路径,注意:路径应采用双\符)
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.persistence.class用于设置持久化类。
五、SSI技术
1、SSI技术说明
<!--#include virtual="/global/foot.jsp"-->
类似jsp中<jsp:include page="/global/foot.jsp"/>
1.1、SSI技术不受运行环境影像,在java,dotnet,cgi等都可以ssi技术。
1.2、sii效率比jsp效率快。
2、SSI技术配置
tomcat 下使用ssi
1、把server/lib/servlets-ssi.renametojar的名称改名为servlets-ssi.jar (tomcat5.5有此步骤,tomcat6则没有此步骤)
2、设置conf/context.xml文件,在<Context>节点添加privileged="true"
3、在conf/web.xml中开启ssi,tomcat提供了两种开启ssi方式。一种是servlet,另一种是filter.
这里我们使用Servlet开启ssi。在web.xml中找到<servlet-name>ssi</servlet-name>,把对该Servlet的注释去掉。
使用SSI filter的话删除在SSI filter和filter-mapping周围的注释
然后根据shtml文件的编码格式指定inputEncoding和outputEncoding属性值。
<servlet>
<servlet-name>ssi</servlet-name>
<servlet-class>org.apache.catalina.ssi.SSIServlet</servlet-class>
这里省略了一些代码
<init-param>
<param-name>inputEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>outputEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<load-on-startup>4</load-on-startup>
</servlet>
当打开了上面servlet的注释之后,我们别忘了也要<servlet-mapping>的注释去掉,如:
<servlet-mapping>
<servlet-name>ssi</servlet-name>
<url-pattern>*.shtml</url-pattern>
</servlet-mapping>
3、SSI范例
3.1、include示范
<!--#include file="foot.jsp"-->
参数:
file 指定包含文件相对于本文档的位置
virtual 指定相对于服务器文档根目录的位置 如 /global/foot.html 表示
注意:文件名称必须带有扩展名。
示例:
<!--#flastmod file="foot.html"-->将当前目录下foot.html文件的最近更新日期插入到当前页面
<!--#fsize file="foot.html"-->将当前目录下news.html的文件大小入到当前页面
main.shtml内容
head.jsp内容:
<%@ page language="java" pageEncoding="UTF-8"%>
这是头部
foot.html内容:
这是尾部
3.2、SSI指令-- #flastmod 和 #fsize
#flastmod 和 #fsize 示范
作用:
#flastmod 文件最近更新日期
#fsize 文件的长度
语法:
<!--#flastmod file="文件名称"-->
<!--#fsize file="文件名称"-->
3.3、SSI指令-- #echo
#echo 示范
作用:将环境变量插入到页面中。
语法:
<!--#echo var="变量名称"-->
示例:
本文档名称:<!--#echo var="DOCUMENT_NAME"--> <br>
你的IP地址:<!--#echo var="REMOTE_ADDR"--> <br>
显示当前文档的虚拟路径:<!--#echo var="DOCUMENT_URI" -->
QUERY_STRING_UNESCAPED:显示未经转义处理的由客户端发送的查询字串,其中所有的特殊字符前面都有转义符"\"。
例如:<!--#echo var="QUERY_STRING_UNESCAPED" -->
<!--#config timefmt=“%Y-%m-%d %a %H:%M:%S”--> %a表示星期几 ,这句是格式化下面输出的时间格式
现在时间:<!--#echo var="DATE_LOCAL"--> <br>
echo命令还可以显示以下环境变量:
SERVER_SOFTWARE:显示服务器软件的名称和版本。例如:
<!--#echo var="SERVER_SOFTWARE" --><br>
SERVER_NAME: 显示服务器的主机名称,DNS别名或IP地址。例如:
<!--#echo var="SERVER_NAME" --><br>
SERVER_PROTOCOL:显示客户端请求所使用的协议名称和版本,如HTTP/1.0。例如:
<!--#echo var="SERVER_PROTOCOL" --><br>
SERVER_PORT:显示服务器的响应端口。例如:
<!--#echo var="SERVER_PORT" --><br>
REQUEST_METHOD:显示客户端的文档请求方法,包括GET, HEAD, 和POST。例如:
<!--#echo var="REQUEST_METHOD" --><br>
REMOTE_HOST:显示发出请求信息的客户端主机名称。
<!--#echo var="REMOTE_HOST" --><br>
REMOTE_ADDR:显示发出请求信息的客户端IP地址。
<!--#echo var="REMOTE_ADDR" --><br>
AUTH_TYPE:显示用户身份的验证方法。
<!--#echo var="AUTH_TYPE" --><br>
REMOTE_USER:显示访问受保护页面的用户所使用的帐号名称。
<!--#echo var="REMOTE_USER" -->
3.4、SSI指令-- #set指令
#set
作用:可给变量赋值,以用于后面的if语句。
语法:
<!--#set var="变量名" value="变量值"-->
示例:
<!--#set var=“varname" value=“lihuoming"-->
3.5、SSI指令-- #if指令
#if
作用:创建可以改变数据的页面,这些数据根据使用if语句时计算的要求予以显示。
语法:
<!--#if expr="$变量名=\"变量值A\""-->
显示内容
<!--#elif expr="$变量名=\"变量值B\""-->
显示内容
<!--#else-->
显示内容
<!--#endif"-->
示例:
<!--#set var="varname" value="b"-->
<!--#if expr="$varname=\"a\""-->
A。
<!--#elif expr="$varname=\"b\"" -->
B。
<!--#else-->
other
<!--#endif"-->
注意:用于前面指令中的反斜杠,是用来代换内部的引号,以便它们不会被解释为结束表达式。不可省略。
一般来说ssi大多使用include指令。