您的位置:首页 > 其它

compass实现搜索、订单载入功能、velocity模版静态化、OSCache优化性能、SSI实现

2012-08-07 15:19 513 查看
一、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;
}

}


ArticleSearchAction内加入如下内容

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、配置



第一步:把上述两个jar文件放置在WEB-INF/lib目录下.

第二步:把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文件设置如下:

cache.memory=true

指定是否使用内存缓存,默认值为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 virtual="/global/foot.jsp"-->

<!--#include file="foot.jsp"-->

参数:

file 指定包含文件相对于本文档的位置

virtual 指定相对于服务器文档根目录的位置 如 /global/foot.html 表示

注意:文件名称必须带有扩展名。

示例:

<!--#flastmod file="foot.html"-->将当前目录下foot.html文件的最近更新日期插入到当前页面

<!--#fsize file="foot.html"-->将当前目录下news.html的文件大小入到当前页面

main.shtml内容

<html xmlns="http://www.w3.org/1999/xhtml"><HEAD>
<TITLE>测试</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
</HEAD>
<BODY>
<!--#include file="head.jsp" -->
<br>中部<br>
<!--#include file="foot.html" -->
</BODY></html>


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" -->

请求完整路径为: <!--#echo var="DOCUMENT_URI" -->?<!--#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指令。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐