在web项目中,为了安全,可能需要把jsp文件放在WEB-INF目录下,这样如果我们的页面中出现超链接a标签或者js的location.href去直接转向到WEB-INF下的某一个jsp页面,那么就会引用不到,因为这样的请求方式是客户端的请求,而WEB-INF页面只对服务端开放,对客户端是不可见的。这时候我们可以使用action,来进行转向,我们先去请求一个action,然后由这个action分发到这个WEB-INF下的页面就可以了。我们可以自己定义一个类似struts1的DispatcherAction的一个action来分发页面。
由于WEB-INF下对客户端是不可见的,所以相关的资源文件,如css,javascript和图片等资源文件不能放在WEB-INF下,那么如何从WEB-INF下引用非WEB-INF下的文件,以及js,html的frame的框架如何去访问WEB-INF下的jsp呢?
下面对WEB-INF目录的一些问题进行详细说明:
以一个项目为例:
如下这样一个代码目录:我们把除index.jsp外其他的jsp文件放在WEB-INF下,把css,javascript,图片放在了webRoot(WebContent)目录下,然后main.jsp是一个frame的html框架,包含了main1.jsp和main2.jsp两个文件。
1、index.jsp页面访问css,js,图片等文件的时候,自然不用说,因为它不在WEB-INF下,正常的访问即可:
-
<
link
href
=
“css/login_css.css”
rel
=
“stylesheet”
type
=
“text/css”
>
-
-
<
script
type
=
“text/javascript”
src
=
“js/login_js.js”
>
</
script
>
-
-
<
img
alt
=
“”
src
=
“image/1.jpg”
>
-
-
2、register.jsp页面去访问css,js和图片的时候,也是不需要添加WEB-INF目录的,也就是忽略WEB-INF目录,访问的时候和index.jsp页面所在的路径访问资源文件是一样的:
-
<
link
href
=
“css/register_css.css”
rel
=
“stylesheet”
type
=
“text/css”
>
-
-
<
script
type
=
“text/javascript”
src
=
“js/register_js.js”
>
</
script
>
-
-
<
img
alt
=
“”
src
=
“image/2.jpg”
>
3、register.jsp页面去转向index.jsp页面,即注册页面有一个链接,转向到登录界面,由于index.jsp页面没有在WEB-INF下,所以可以直接访问index.jsp页面的路径,
register.jsp:
-
<
tr
>
-
-
<
td
>
</
td
>
-
-
<
td
colspan
=
“2”
style
=
“float: left; ”
>
-
-
<
button
type
=
“button”
>
注册
</
button
>
-
-
<
button
type
=
“button”
onclick
=
“goLogin()”
>
去登录
</
button
>
-
-
</
td
>
-
-
</
tr
>
在register.jsp页面中定义了一个botton,然后响应一个onclick事件,
我们在register_js.js中定义这个
goRegister
()的js事件:
regitster_js.js:
这样就可以访问到WebContent目录中的index.jsp页面了。
4、index.jsp(登录页面)有一个链接,指向register页面,如果点击链接,就跳转到register.jsp中进行注册,因为register.jsp在WEB-INF下,所以不可以直接使用a标签去访问WEB-INF路径下的文件:
,或者js的location.href去访问:
这样两种方式都是直接请求了WEB-INF路径,都是无法跳转的。
我们可以建立一个action,struts的action中没有DispatcherAction,但是我们可以通过通配符来让一个action的不同方法返回不同的页面,然后我们去请求这个action中的相应方法即可由这个action从服务器端请求到WEB-INF下的页面了:
下面详细说明如果进行自定义的分发action来进行页面的分发:
DispatcherAction.java:
-
package
com.yun.test.webinf.action;
-
-
import
com.opensymphony.xwork2.ActionSupport;
-
publicclass DispatcherAction
extends
ActionSupport{
-
public
String goRegister(){
-
-
return
“goRegister”
;
-
-
}
-
}
这个action中,我们定义了一个goRegister的方法,这个方法没有任何逻辑代码,只是返回一个字符串,然后在struts.xml中我们让这个字符串指向我们要访问的WEB-INF下的register.jsp页面:
struts.xml:
-
<
action
name
=
“dispatcher”
class
=
“com.yun.test.webinf.action.DispatcherAction”
>
-
-
<
result
name
=
“goRegister”
>
WEB-INF/register/register.jsp
</
result
>
-
-
<
result
name
=
“input”
>
/index.jsp
</
result
>
-
-
</
action
>
然后我们可以在页面中进行请求DispatcherAction的goRegister方法,然后这个action的goRegister方法就会把页面转向到WEB-INF下的register.jsp页面了:
我们在index.jsp中定义了一个botton,然后给这个botton注册一个点击事件:
index.jsp:
-
<
tr
>
-
-
<
td
>
</
td
>
-
-
<
td
colspan
=
“2”
style
=
“float: left; ”
>
-
-
<
button
onclick
=
“checkValues()”
>
登录
</
button
>
-
-
<
button
type
=
“button”
id
=
“button1”
onclick
=
“goRegister()”
>
去注册
</
button
>
-
-
</
td
>
-
-
</
tr
>
-
-
在index_js.js中定义这个点击事件为location.href到定义的action的goRegister.action方法中:
login_js.js:
当然,也可以直接在页面中使用a标签来请求这个action的goRegister方法:
这样我们就可以通过action的转发,成功的请求道WEB-INF下的jsp文件了。
注意请求action的方式,
dispatcher!goRegister.action
这个!是一个分发字符,!之前的部分是action的名字,!之后的部分是这个action的某个我们要请求的方法的名字。然后这个action中必须要定义一个同名的方法,就不需要使用execute方法了。然后这个同名方法,返回的是一个String字符串,这个字符串在struts.xml中指向为我们想要跳转的路径。这就是一个请求分发的action。
我们还可以自己定义分发的分隔符,可以是下划线等,分发action详见Struts2实现分发的action一节
5、jsp页面中的frame框架中想把多个WEB-INF下的页面设置为框架的内容的时候,即使main.jsp和main1.jsp,main2.jsp同在WEB-INF目录下,也不可以直接去指定WEB-INF路径,如:
-
<
frameset
cols
=
“30%,70%”
>
-
-
<
frame
src
=
“main/main1.jsp”
>
-
-
<
frame
src
=
“main/main1.jsp”
>
-
-
</
frameset
>
这样还是不能访问,也必须使用服务端的action分发的方式进行指定jsp文件的路径。
代码如下:
main.jsp:
-
<
%@ page
language
=
“java”
contentType
=
“text/html; charset=UTF-8”
-
-
pageEncoding
=
“UTF-8”
%
>
-
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”
>
-
<
html
>
-
<
head
>
-
<
meta
http-equiv
=
“Content-Type”
content
=
“text/html; charset=UTF-8”
>
-
<
title
>
main
</
title
>
-
</
head
>
-
<
frameset
cols
=
“30%,70%”
>
-
-
<
frame
src
=
“dispatcher!goMain1.action”
>
-
-
<
frame
src
=
“dispatcher!goMain2.action”
>
-
-
</
frameset
>
-
</
html
>
struts.xml:
-
<?
xml
version
=
“1.0”
encoding
=
“UTF-8”
?>
-
-
<!DOCTYPE struts PUBLIC
-
-
“-//Apache Software Foundation//DTD Struts Configuration 2.0//EN”
-
-
“http://struts.apache.org/dtds/struts-2.0.dtd”
>
-
-
-
-
<
struts
>
-
-
<
package
name
=
“test”
extends
=
“struts-default”
>
-
-
<
action
name
=
“dispatcher”
class
=
“com.yun.test.webinf.action.DispatcherAction”
>
-
-
<
result
name
=
“goRegister”
>
WEB-INF/register/register.jsp
</
result
>
-
-
<
result
name
=
“goMain1”
>
WEB-INF/main/main1.jsp
</
result
>
-
-
<
result
name
=
“goMain2”
>
WEB-INF/main/main2.jsp
</
result
>
-
-
<
result
name
=
“input”
>
/index.jsp
</
result
>
-
-
</
action
>
-
-
<
action
name
=
“login”
class
=
“com.yun.test.webinf.action.LoginAction”
>
-
-
<
result
name
=
“success”
>
WEB-INF/main.jsp
</
result
>
-
-
<
result
name
=
“input”
>
/index.jsp
</
result
>
-
-
</
action
>
-
-
<
action
name
=
“register”
class
=
“com.yun.test.webinf.action.RegisterAction”
>
-
-
<
result
name
=
“success”
>
WEB-INF/main.jsp
</
result
>
-
-
<
result
name
=
“input”
>
WEB-INF/register/register.jsp
</
result
>
-
-
</
action
>
-
</
package
>
-
<!– 定义struts标签为无默认样式 –>
-
-
<
constant
name
=
“struts.ui.theme”
value
=
“simple”
/>
-
-
</
struts
>
-
-
DispatcherAction.java:
-
package
com.yun.test.webinf.action;
-
-
import
com.opensymphony.xwork2.ActionSupport;
-
-
publicclass DispatcherAction
extends
ActionSupport{
-
public
String goRegister(){
-
return
“goRegister”
;
-
-
}
-
-
public
String goMain1(){
-
return
“goMain1”
;
-
}
-
-
public
String goMain2(){
-
-
return
“goMain2”
;
-
-
}
-
}
这样,这个main页面就可以通过action分发使用frame框架了。
6、同在WEB-INF目录下的register.jsp和main.jsp中怎么跳转呢?我们会在register.jsp中提交表单,然后在action中进行处理,如果注册成功,会跳转到main页面,这时的跳转也会涉及到WEB-INF目录,因为目标路径main.jsp也在WEB-INF下,所以我们在跳转的时候也必须写上WEB-INF的目录路径才可以,而且必须是请求分发,而不能是redirct的方式。
如代码:
register.jsp:
-
<
%@ page
language
=
“java”
contentType
=
“text/html; charset=UTF-8”
-
-
pageEncoding
=
“UTF-8”
%
>
-
-
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”
>
-
-
<
html
>
-
-
<
head
>
-
-
<
meta
http-equiv
=
“Content-Type”
content
=
“text/html; charset=UTF-8”
>
-
-
<
title
>
register
</
title
>
-
-
<
link
href
=
“css/register_css.css”
rel
=
“stylesheet”
type
=
“text/css”
>
-
-
<
script
type
=
“text/javascript”
src
=
“js/register_js.js”
>
</
script
>
-
-
</
head
>
-
-
<
body
>
-
<
div
id
=
“content”
>
-
-
<
form
action
=
“register.action”
id
=
“registerForm”
method
=
“post”
>
-
<
table
>
-
-
<
tr
>
-
-
<
td
width
=
“150px;”
style
=
“text-align:center; ”
>
注册名
</
td
>
-
-
<
td
width
=
“80px;”
style
=
“text-align: left;”
>
<
input
type
=
“text”
name
=
“user.username”
id
=
“username”
>
</
td
>
-
-
<
td
width
=
“400px;”
style
=
“text-align: left;”
>
<
font
color
=
“red”
>
* 请输入用户名
</
font
>
</
td
>
-
-
</
tr
>
-
-
<
tr
>
-
-
<
td
width
=
“100px;”
style
=
“text-align:center; ”
>
注册密码
</
td
>
-
-
<
td
width
=
“80px;”
style
=
“text-align: left;”
>
<
input
type
=
“password”
name
=
“user.password”
size
=
“22”
id
=
“password”
>
</
td
>
-
-
<
td
width
=
“400px;”
style
=
“text-align: left;”
>
<
font
color
=
“red”
>
* 请输入密码
</
font
>
</
td
>
-
-
</
tr
>
-
-
<
tr
>
-
-
<
td
>
</
td
>
-
-
<
td
colspan
=
“2”
style
=
“float: left; ”
>
-
-
<
button
type
=
“button”
onclick
=
“checkValues()”
>
注册
</
button
>
-
-
<
button
type
=
“button”
onclick
=
“goLogin()”
>
去登录
</
button
>
-
-
</
td
>
-
-
</
tr
>
-
-
</
table
>
-
-
-
-
</
form
>
-
-
</
div
>
-
-
<
img
alt
=
“”
src
=
“image/2.jpg”
>
-
-
</
body
>
-
-
</
html
>
-
-
struts.xml:
-
<?
xml
version
=
“1.0”
encoding
=
“UTF-8”
?>
-
-
<!DOCTYPE struts PUBLIC
-
-
“-//Apache Software Foundation//DTD Struts Configuration 2.0//EN”
-
-
“http://struts.apache.org/dtds/struts-2.0.dtd”
>
-
<
struts
>
-
-
<
package
name
=
“test”
extends
=
“struts-default”
>
-
-
<
action
name
=
“dispatcher”
class
=
“com.yun.test.webinf.action.DispatcherAction”
>
-
-
<
result
name
=
“goRegister”
>
WEB-INF/register/register.jsp
</
result
>
-
-
<
result
name
=
“goMain1”
>
WEB-INF/main/main1.jsp
</
result
>
-
-
<
result
name
=
“goMain2”
>
WEB-INF/main/main2.jsp
</
result
>
-
-
<
result
name
=
“input”
>
/index.jsp
</
result
>
-
-
</
action
>
-
-
<
action
name
=
“login”
class
=
“com.yun.test.webinf.action.LoginAction”
>
-
-
<
result
name
=
“success”
>
WEB-INF/main.jsp
</
result
>
-
-
<
result
name
=
“input”
>
/index.jsp
</
result
>
-
-
</
action
>
-
-
<
action
name
=
“register”
class
=
“com.yun.test.webinf.action.RegisterAction”
>
-
-
<
result
name
=
“success”
>
WEB-INF/main.jsp
</
result
>
-
-
<
result
name
=
“input”
>
WEB-INF/register/register.jsp
</
result
>
-
-
</
action
>
-
-
-
-
</
package
>
-
-
-
-
<!– 定义struts标签为无默认样式 –>
-
-
<
constant
name
=
“struts.ui.theme”
value
=
“simple”
/>
-
-
</
struts
>
-
-
RegisterAction.java:
-
package
com.yun.test.webinf.action;
-
-
import
com.opensymphony.xwork2.ActionSupport;
-
-
import
com.yun.test.webinf.entity.User;
-
public
class
RegisterAction
extends
ActionSupport{
-
private
User user;
-
public
void
setUser(User user) {
-
this
.user = user;
-
-
}
-
-
public
User getUser() {
-
return
user;
-
-
}
-
-
@Override
-
-
public
String execute()
throws
Exception {
-
-
if
(
“lisi”
.equals(user.getUsername())&&
“lisi”
.equals(user.getPassword())){
-
-
return
SUCCESS;
-
-
}
-
-
return
INPUT;
-
-
}
-
-
-
-
}
接下来对WEB-INF页面中的注意事项进行说明:
1. 把页面资源文件只能放在WebContent目录内,,如 CSS,JS,image等.不能放在WEB-INF下,因为WEB-INF是对客户端隐藏的,所以放在WEB-INF下会造成页面的布局等文件引用不到的情况。
2. 页面文件一般放在WEB-INF目录下面,这样可以限制访问,提高安全性.如JSP,html文件,放在WEB-INF目录下就可以避免客户端直接在地址栏上输入路径进行访问了。基于不同的功能 ,把JSP 放置在WEB-INF下的不同的目录中。
3. 只能用转向方式来访问WEB-INF目录下的JSP,不用采用重定向的方式请求该目录里面的任何资源。
4.转向方式:
4.1、请求转发:
如struts.xml文件中配置
或在Action中写
request.getRequestDispatcher(“/WEB-INF/main/main2.jsp”).forward(request, response);
的方式都是服务器读取了该页面内容,并发送到客户端的,客户端的地址不变,然后内容跳转了。这样的方式是可以访问到WEB-INF目录下的jsp文件的。
4.2、重定向方式:
如struts.xml文件中配置
或在action中
response.sendRedirect(“WEB-INF/main/main2.jsp “);
都属于重定向的方式,重定向的含义就是服务器把地址发给客户端,让客户端去访问,这样还是在客户端访问的WEB-INF目录,所以是无法访问到WEB-INF目录下的jsp文件的。
5、有一些标签,也是可以访问到WEB-INF目录中的文件的,如果符合要求的情况下也可以使用,如:
-
<
jsp:forward
page
=
“/WEB-INF/jsp/test/test.jsp”
/>
-
-
<
a
href
=
“javascript:<jsp:forward page=’WEB-INF/xxxx.jsp’/>”
>
</
a
>
-
-
<
jsp:include
page
=
“WEB-INF/xxx.jsp”
>
都是可以访问WEB-INF下的jsp文件的。但是局限性很大,还是建议使用action分发的方式。