struts action2开发中,想在action中读取数据库,然后将结果返回给jsp,显示出来。想知道action和jsp之间如何传递

博客分类:
早在我刚学Struts2之初的时候,就想写一篇文章来阐述Struts2如何返回JSON数据的原理和具体应用了,但苦于一直忙于工作难以抽身,渐渐的也淡忘了此事。直到前两天有同事在工作中遇到这个问题,来找我询问,我又细细地给他讲了一遍之后,才觉得无论如何要抽一个小时的时间来写这篇文章,从头到尾将Struts2与JSON的关系说清楚。
其实网络中,关于这个问题的答案已是海量,我当初也是从这海量的答案中吸收精华,才将“Struts2返回JSON数据”这个问题搞清楚的。但是这些海量的答案,有一个共同的缺陷,就是作者们只关注问题核心,即“如何在具体的Struts2应用中返回JSON数据到客户端”如何实现,而对于"为何要这样实现"以及实现的本质却解释的不甚了了,在笔者看来这只是“授人以鱼”而非笔者所推崇的“授人以鱼的同时,授人以渔”。在这篇文章中,笔者将总结前辈们的经验,并结合自己的理解,来从理论到实践由浅入深的说明“Struts2返回JSON数据”这一问题。
JSON(JavaScript Object Notation)
首先来看一下JSON官方对于“JSON”的解释:
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。(更多内容请参见JSON官网)
JSON建构于两种结构:
“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
因为JSON中的值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array),且这些结构可以嵌套,这种特性给予JSON表达数据以无限的可能:它既可以表达一个简单的key/value,也可以表达一个复杂的Map或List,而且它是易于阅读和理解的。
Struts2中JSON的用武之地
因为JSON是脱离语言的理想的数据交换格式,所以它被频繁的应用在客户端与服务器的通信过程中,这一点是毋庸置疑的。而在客户端与服务器的通信过程中,JSON数据的传递又被分为服务器向客户端传送JSON数据,和客户端向服务器传送JSON数据,前者的核心过程中将对象转换成JSON,而后者的核心是将JSON转换成对象,这是本质的区别。另外,值得一提的是,JSON数据在传递过程中,其实就是传递一个普通的符合JSON语法格式的字符串而已,所谓的“JSON对象”是指对这个JSON字符串解析和包装后的结果,这一点请牢记,因为下面的内容会依赖这一点。
Struts2返回JSON数据到客户端
这是最常见的需求,在AJAX大行其道的今天,向服务器请求JSON数据已成为每一个WEB应用必备的功能。抛开Struts2暂且不提,在常规WEB应用中由服务器返回JSON数据到客户端有两种方式:一是在Servlet中输出JSON串,二是在JSP页面中输出JSON串。上文提到,服务器像客户端返回JSON数据,其实就是返回一个符合JSON语法规范的字符串,所以在上述两种 方法中存在一个共同点,就是将需要返回的数据包装称符合JSON语法规范的字符串后在页面中显示。如下所示
使用Servlet返回JSON数据到客户端:
package cn.ysh.studio.struts2.json.demo.
import java.io.IOE
import java.io.PrintW
import javax.servlet.ServletE
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import net.sf.json.JSONO
import cn.ysh.studio.struts2.json.demo.bean.U
public class JSON extends HttpServlet {
private static final long serialVersionUID = 1L;
* The doGet method of the servlet. &br&
* This method is called when a form has its tag value method equals to get.
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
//将要被返回到客户端的对象
User user=new User();
user.setId("123");
user.setName("JSONServlet");
user.setPassword("JSON");
user.setSay("Hello , i am a servlet !");
JSONObject json=new JSONObject();
json.accumulate("success", true);
json.accumulate("user", user);
out.println(json.toString());
因为JSON数据在传递过程中是以普通字符串形式传递的,所以我们也可以手动拼接符合JSON语法规范的字符串输出到客户端
以下这两句的作用与38-46行代码的作用是一样的,将向客户端返回一个User对象,和一个success字段
String jsonString="{\"user\":{\"id\":\"123\",\"name\":\"JSONServlet\",\"say\":\"Hello , i am a servlet !\",\"password\":\"JSON\"},\"success\":true}";
out.println(jsonString);
out.flush();
out.close();
* The doPost method of the servlet. &br&
* This method is called when a form has its tag value method equals to post.
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
结果在意料之中,如下图所示:
使用JSP(或html等)返回JSON数据到客户端:
&%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%&
{"user":{"id":"123","name":"JSONJSP","say":"Hello , i am a JSP !","password":"JSON"},"success":true}
这个就不用去看结果了吧。
再回到Struts,在Struts的MVC模型中,Action替代Servlet担当了Model的角色,所以对于Struts而言,返回JSON数据到客户端,跟传统的WEB应用一样,存在两种方式,即在Action中输出JSON数据,和在视图资源中输出JSON数据。再往下细分的话,在Action中输出JSON数据又分为两种方式,一是使用传统方式输出自己包装后的JSON数据,二是使用Struts自带的JSON数据封装功能来自动包装并返回JSON数据。
在视图资源中输出JSON数据
Action处理完用户请求后,将数据存放在某一位置,如request中,并返回视图,然后Struts将跳转至该视图资源,在该视图中,我们需要做的是将数据从存放位置中取出,然后将其转换为JSON字符串,输出在视图中。这跟传统WEB应用中在JSP页面输出JSON数据的做法如出一辙:
public String testByJSP() {
User user = new User();
user.setId("123");
user.setName("Struts2");
user.setPassword("123");
user.setSay("Hello world !");
JSONObject jsonObject=new JSONObject();
jsonObject.accumulate("user", user);
//这里在request对象中放了一个data,所以struts的result配置中不能有type="redirect"
ServletActionContext.getRequest().setAttribute("data", jsonObject.toString());
return SUCCESS;
因为是常规的Struts流程配置,所以配置内容就不再展示了。
JSP代码就非常简单了,
&%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%&
结果如图所示:
在Action中以传统方式输出JSON数据
这一点跟传统的Servlet的处理方式基本上一模一样,代码如下
public void doAction() throws IOException{
HttpServletResponse response=ServletActionContext.getResponse();
//以下代码从JSON.java中拷过来的
response.setContentType("text/html");
out = response.getWriter();
//将要被返回到客户端的对象
User user=new User();
user.setId("123");
user.setName("JSONActionGeneral");
user.setPassword("JSON");
user.setSay("Hello , i am a action to print a json!");
JSONObject json=new JSONObject();
json.accumulate("success", true);
json.accumulate("user", user);
out.println(json.toString());
因为JSON数据在传递过程中是以普通字符串形式传递的,所以我们也可以手动拼接符合JSON语法规范的字符串输出到客户端
以下这两句的作用与38-46行代码的作用是一样的,将向客户端返回一个User对象,和一个success字段
String jsonString="{\"user\":{\"id\":\"123\",\"name\":\"JSONActionGeneral\",\"say\":\"Hello , i am a action to print a json!\",\"password\":\"JSON\"},\"success\":true}";
out.println(jsonString);
out.flush();
out.close();
struts.xml中的配置:
&package name="default" extends="struts-default" namespace="/"&
&action name="testJSONFromActionByGeneral" class="cn.ysh.studio.struts2.json.demo.action.UserAction" method="doAction"&
&/package&
注意:这个action没有result,且doAction方法没有返回值!
就不再贴图了,因为结果可想而知!
在Action中以Struts2的方式输出JSON数据
本着“不重复发明轮子”的原则,我们将转换JSON数据的工作交给Struts2来做,那么相对于在Action中以传统方式输出JSON不同的是,Action是需要将注意力放在业务处理上,而无需关心处理结果是如何被转换成JSON被返回客户端的——这些 工作通过简单的配置,Struts2会帮我们做的更好。
public String testByAction() {
// dataMap中的数据将会被Struts2转换成JSON字符串,所以这里要先清空其中的数据
dataMap.clear();
User user = new User();
user.setId("123");
user.setName("JSONActionStruts2");
user.setPassword("123");
user.setSay("Hello world !");
dataMap.put("user", user);
// 放入一个是否操作成功的标识
dataMap.put("success", true);
// 返回结果
return SUCCESS;
struts.xml中action的配置:
&package name="json" extends="json-default" namespace="/test"&
&action name="testByAction"
class="cn.ysh.studio.struts2.json.demo.action.UserAction" method="testByAction"&
&result type="json"&
&!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 --&
&param name="root"&dataMap&/param&
&/package&
凡是使用Struts2序列化对象到JSON的action,所在的package必须继承自json-default,注意,这里唯一的result,没有指定name属性。
结果如下图所示:
上面很详细的说明了在WEB应用中如何返回JSON数据到客户端,讲了那么多种方式,涉及的技术核心无非只有两点:
1、将对象转换成符合JSON语法格式的字符串;2、将符合JSON语法格式的字符串返回客户端;
第二点是整个实现过程的本质,但却不难做到;第一点其实也不难,他甚至有两种做法,一是通过字符串拼接方式,而是通过JSONObject以对象方式转换。看下面的一个例子:
package cn.ysh.studio.struts2.json.demo.
import cn.ysh.studio.struts2.json.demo.bean.U
import net.sf.json.JSONO
public class JSONTest {
* 将普通的pojo转换成JSON字符串
public JSONObject bean2json() {
User user = new User();
user.setId("JSONTest");
user.setName("JSONTest");
user.setPassword("JSON");
user.setSay("Hello,i am JSONTest.java");
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("user", user);
System.out.println("User转换后的字符串:"+jsonObject.toString());
return jsonO
* 从JSONObject对象中反向解析出User对象
* @param jsonObject
public void json2bean(JSONObject jsonObject) {
User user=(User)JSONObject.toBean((JSONObject)jsonObject.get("user"),User.class);
System.out.println("转换得到的User对象的Name为:"+user.getName());
public static void main(String[] s) {
JSONTest tester=new JSONTest();
tester.json2bean(tester.bean2json());
JSON格式的字符串返回到客户端后,客户端会将其解析并封装成真正的JSON对象,以供JS调用。
总结上述,其实只要明白了服务器返回JSON数据到客户端的原理,做起来就游刃有余了,他甚至有非常多的可选方案,但既然是基于Struts2的实现,那么肯定还是要用Struts2的方式来做啦,因为这样确实可以省很多事。另外,在文章的最后,说明一下返回JSON数据时在result中配置的参数的含义及其常见常见配置吧:
&result type="json"&
&!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 --&
&!-- 默认将会序列所有有返回值的getter方法的值,而无论该方法是否有对应属性 --&
&param name="root"&dataMap&/param&
&!-- 指定是否序列化空的属性 --&
&param name="excludeNullProperties"&true&/param&
&!-- 这里指定将序列化dataMap中的那些属性 --&
&param name="includeProperties"&
userList.*
&!-- 这里指定将要从dataMap中排除那些属性,这些排除的属性将不被序列化,一半不与上边的参数配置同时出现 --&
&param name="excludeProperties"&
值得一提的是通过Struts2来返回JSON数据,在IE中会提示下载,这个不用关心,换个浏览器就能正常展示JSON数据,而在JS调用中,更是毫无影响。
下面是整个Action的完整代码:
package cn.ysh.studio.struts2.json.demo.
import java.io.IOE
import java.io.PrintW
import java.util.HashM
import java.util.M
import javax.servlet.http.HttpServletR
import org.apache.struts2.ServletActionC
import net.sf.json.JSONO
import cn.ysh.studio.struts2.json.demo.bean.U
import com.opensymphony.xwork2.ActionS
public class UserAction extends ActionSupport {
private static final long serialVersionUID = 1L;
//将会被Struts2序列化为JSON字符串的对象
private Map&String, Object& dataM
* 构造方法
public UserAction() {
//初始化Map对象
dataMap = new HashMap&String, Object&();
* 测试通过action以视图方式返回JSON数据
public String testByJSP() {
User user = new User();
user.setId("123");
user.setName("JSONActionJSP");
user.setPassword("123");
user.setSay("Hello world !");
JSONObject jsonObject=new JSONObject();
jsonObject.accumulate("user", user);
jsonObject.accumulate("success", true);
//这里在request对象中放了一个data,所以struts的result配置中不能有type="redirect"
ServletActionContext.getRequest().setAttribute("data", jsonObject.toString());
return SUCCESS;
* 测试通过action以Struts2默认方式返回JSON数据
public String testByAction() {
// dataMap中的数据将会被Struts2转换成JSON字符串,所以这里要先清空其中的数据
dataMap.clear();
User user = new User();
user.setId("123");
user.setName("JSONActionStruts2");
user.setPassword("123");
user.setSay("Hello world !");
dataMap.put("user", user);
// 放入一个是否操作成功的标识
dataMap.put("success", true);
// 返回结果
return SUCCESS;
* 通过action是以传统方式返回JSON数据
* @throws IOException
public void doAction() throws IOException{
HttpServletResponse response=ServletActionContext.getResponse();
//以下代码从JSON.java中拷过来的
response.setContentType("text/html");
out = response.getWriter();
//将要被返回到客户端的对象
User user=new User();
user.setId("123");
user.setName("JSONActionGeneral");
user.setPassword("JSON");
user.setSay("Hello , i am a action to print a json!");
JSONObject json=new JSONObject();
json.accumulate("success", true);
json.accumulate("user", user);
out.println(json.toString());
因为JSON数据在传递过程中是以普通字符串形式传递的,所以我们也可以手动拼接符合JSON语法规范的字符串输出到客户端
以下这两句的作用与38-46行代码的作用是一样的,将向客户端返回一个User对象,和一个success字段
String jsonString="{\"user\":{\"id\":\"123\",\"name\":\"JSONActionGeneral\",\"say\":\"Hello , i am a action to print a json!\",\"password\":\"JSON\"},\"success\":true}";
out.println(jsonString);
out.flush();
out.close();
* Struts2序列化指定属性时,必须有该属性的getter方法,实际上,如果没有属性,而只有getter方法也是可以的
public Map&String, Object& getDataMap() {
return dataM
完整的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"&
&package name="json" extends="json-default" namespace="/test"&
&action name="testByAction"
class="cn.ysh.studio.struts2.json.demo.action.UserAction" method="testByAction"&
&result type="json"&
&!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 --&
&!-- 默认将会序列所有有返回值的getter方法的值,而无论该方法是否有对应属性 --&
&param name="root"&dataMap&/param&
&!-- 指定是否序列化空的属性 --&
&param name="excludeNullProperties"&true&/param&
&!-- 这里指定将序列化dataMap中的那些属性 --&
&param name="includeProperties"&
userList.*
&!-- 这里指定将要从dataMap中排除那些属性,这些排除的属性将不被序列化,一半不与上边的参数配置同时出现 --&
&param name="excludeProperties"&
&/package&
&package name="default" extends="struts-default" namespace="/"&
&action name="testJSONFromActionByGeneral"
class="cn.ysh.studio.struts2.json.demo.action.UserAction" method="doAction"&
&action name="testByJSP"
class="cn.ysh.studio.struts2.json.demo.action.UserAction" method="testByJSP"&
&result name="success"&/actionJSP.jsp&/result&
&/package&
最后,附上整个范例工程(一个MyEclipse工程)源码。
原创文章,转载请注明出处:
(109.5 KB)
下载次数: 2240
浏览 66415
值得一提的是通过Struts2来返回JSON数据,在IE中会提示下载,这个不用关心,换个浏览器就能正常展示JSON数据,而在JS调用中,更是毫无影响。其实关心的就是这个问题,怎么把提示框消除掉首先这个问题是因为IE无法判断服务器返回的数据的类型,默认它会认为是流数据,所以弹出下载框提示保存,对于JS毫无影响。如果你非要在意这个问题,可以在后台通过response设置HTTP头,告知浏览器服务器返回的数据是text/html格式到文本数据,那么IE就能像FF那样自动呈现文本内容,而不是弹窗了。
& 上一页 1
浏览: 238516 次
来自: 上海
求份源码,感谢楼主,
楼主你这个右上角的button按钮控件布局是怎么弄的啊
没有AWTUtilities这个类怎么办呀!!!
还有如果我想放一组user对象而不是一个怎么办呢?
请问userList.*是什么意思?
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'Ajax调用action后,jsp页面怎么获取action的返回数据?action要改什么吗?_百度知道
Ajax调用action后,jsp页面怎么获取action的返回数据?action要改什么吗?
我有更好的答案
type: &post&,
url : &/manager/mobileSet.do?method=replaceCss&,
dataType:'json',
data:'colorType='+color,
success: function(result){
alert(result); //这里我想接收到action里边的字符串,怎么写 ?
}});后台java代码:String result = “xxxxxxxxxxxxxxx”;PrintWriter out = this.servletResponse.getWriter();
out.write(result);
采纳率:74%
来自团队:
List数组最好换为json的,$.post(&action路径&,function(data返回的数据){你最好弹一下,看是不是你要的数据eval(&var mydata=&+data);再用each循环就好});
没有返回list 数据的...只能是xml 或者json.然后在前台解析
为您推荐:
其他类似问题
ajax的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
刚刚学习 struts2 ,在做一个图书展示的简单页面,问题如下:1.数据库里面有一个表 book ,有这四个字段: id,name,price,count ,有几条记录。2.我建立了一个 index.jsp 的页面用于登陆(已经成功),登陆后通过 struts.xml 跳转到 userindex.jsp 中。3.我建立了一个 action 叫做,用于读取所有的图书信息(数据库访问),里面建立了一个 list , 有 get 和 set 的方法。4.userindex.jsp 的页面是这样写的:
&s:iterator value="list" status="st"&
&td&&s:property value="id"/&&/td&
&td&&s:property value="name"/&&/td&
&td&&s:property value="price"/&&/td&
&td&&s:property value="count"/&&/td&
/s:iterator
现在 userindex.jsp 什么也没有现在的问题是,我刚学 struts2 ,知道需要 action 来处理逻辑,可是如何把 BookInfoAction 和 userindex.jsp 结合起来, 我已经实现了登陆功能,是配置 struts.xml 中
&action name="login" class="shopping.LoginAction" method="login"&
&result name="loginout"&helloworld.jsp&/result&
&result name="loginin" type="redirect"&userindex.jsp&/result&
可是我怎么把这个展示图书的页面和 我的 action 结合起来呢? 我如何才能做到登陆成功之后的页面( userindex.jsp )里面就可以直接显示所有的图书呢?
我一定是落下了什么步骤,这个我也是知道的,可是我搜了资料看了教程都没有提及,希望大家帮助我,谢谢!
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
&result name="loginin" type="redirect"&这个地方是要redirect的action名字&/result&
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。如何在jsp中获取action传递过来的数据?_百度知道
如何在jsp中获取action传递过来的数据?
我使用struts2开发,在action中使用HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute(&userid&, uu.getId());
传递一个数据,在页面我使用
&input type=&text& id=&user.id& name=&user.id& value=&${ userid...
我有更好的答案
  jsp中获取action传递过来的数据代码如下:Map request = (Map) ActionContext.getContext().get(&request&);既然你知道request是一个已存在的对象,在定义对象时就不要再用request这个名字,容易给他人以及自己以后造成误解用struts2标签可以这么做&s:iterator value=&request&&
&s:property value=&empId& /&
&s:property value=&eName& /&
&s:property value=&eSex& /&
&s:property value=&eSex& /&
&s:property value=&eSalary& /&&/s:iterator&
采纳率:65%
来自团队:
使用struts2的标签库吧,&s:property value=&#session.userid&/&你那个可以使用必须加上 sessionScope 如
${ sessionScope.userid}
为您推荐:
其他类似问题
您可能关注的内容
jsp的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。Struts2一个Action内包含多个请求处理方法的处理,method的使用方法,struts2中-马札伯格
如果我吻你,你就微笑,我就吻你。
struts2的关于method=“{1}&意思详解&action & name=&&Login_*&&&& method=&&{1}&&&& class=&&mailreader2.Login &&中Login_*带*是什么意思?method=&&{1}&&带{}这个是什么意思?====================================================name=&&Login_*&&代表这个action处理所有以Login_开头的请求method=&&{1}&&根据前面请求Login_methodname,调用action中的以methodname命名的方法class=&&mailreader2.Login &action的类名称如jsp文件中请求Login_validateUser的action名称,根据上面配置,调用action类mailreader2.Login类中方法validateUser()又如:对于Login_update请求,将会调用mailreader2.Login的update()方法。它的用法同webwork中的!符号的作用,相当于是一个通配符。&&+++++++++++++++++++++++++++++++++++++++++++++++++++++++Struts2 学习笔记4--Action Method--接收参数文章分类:Java编程struts2中的路径问题注意:在jsp中”/”表示tomcat服务器的根目录,在struts.xml配置文件中”/”表示webapp的根路径,即MyEclipse web项目中的WebRoot路径。总结:struts2中的路径问题是根据action的路径而不是jsp路径来确定,所以尽量不要使用相对路径&。虽然可以用redirect方式解决,但redirect方式并非必要。解决办法非常简单,统一使用绝对路径。(在jsp中用request.getContextRoot方式来拿到webapp的路径)或者使用myeclipse经常用的,指定basePath。&Action Method配置:&&&&&package name=&user& extends=&struts-default& namespace=&/user&&&&&&&&&&&action name=&userAdd& class=&com.bjsxt.struts2.user.action.UserAction& method=&add&&&&&&&&&&&&&&&result&/user_add_success.jsp&/result&&&&&&&&&&/action&&&&&&&&&&&&&&&&&action name=&user& class=&com.bjsxt.struts2.user.action.UserAction&&&&&&&&&&&&&&&result&/user_add_success.jsp&/result&&&&&&&&&&/action&&&&&&/package&总结:Action执行的时候并不一定要执行execute方法1、可以在配置文件中配置Action的时候用method=来指定执行哪个方法(前者方法)2、也可以在url地址中动态指定(动态方法调用DMI )(推荐)(后者方法)&a href=&&%=context %&/user/userAdd&&添加用户&/a&&br /&&a href=&&%=context %&/user/user!add&&添加用户&/a&&br /&前者会产生太多的action,所以不推荐使用。(注:&% String context = request.getContextPath();&%&)再给个案例,大概介绍!使用动态调用DMI的方法,即通过!+方法名的指定方法:UserAction.javaimport com.opensymphony.xwork2.ActionCimport java.util.Mpublic class UserAction { private String userN private S& public String getUserName()&{& return userN&} public void setUserName(String userName)&{& this.userName = userN&} public String getPassword()&{&&} public void setPassword(String password)&{& this.password =&} public String execute(){& if(!userName.equals(&aa&)||!password.equals(&aa&)){&& return &error&;&&}else{&& Map session=(Map)ActionContext.getContext().getSession();&& session.put(&userName&, userName);&& return &success&;&&}&}& public String loginOther(){& if(!userName.equals(&bb&)||!password.equals(&bb&)){&& return &error&;&&}else{&& Map session=(Map)ActionContext.getContext().getSession();&& session.put(&userName&, userName);&& return &success&;&&}&}}struts.xml&?xml version=&1.0& encoding=&UTF-8&?&&!DOCTYPE struts PUBLIC&-//Apache Software Foundation//DTD Struts Configuration 2.0//EN&&&&&struts&&&package name=&default& extends=&struts-default&&&&&action name=&struts& class=&org.action.StrutsAction&&&&&&result name=&success&&/welcome.jsp&/result&&&&&result name=&error&&/hello.jsp&/result&&&&&result name=&input&&/hello.jsp&/result&&&&/action&&&&action name=&user& class=&org.action.UserAction&&&&&&result name=&success&&/login_welcome.jsp&/result&&&&&result name=&error&&/login_error.jsp&/result&&&&/action&&&&!--&action name=&loginOther& class=&org.action.UserAction& method=&loginOther&&&&&&result name=&success&&/login_welcome.jsp&/result&&&&&result name=&error&&/login_error.jsp&/result&&&&/action&&--&&/package&&/struts&&login_welcome.jsp&%@ page language=&java& import=&java.util.*& pageEncoding=&utf-8&%&&%@ taglib uri=&/struts-tags& prefix=&s&&%&&!DOCTYPE HTML PUBLIC &-//W3C//DTD HTML 4.01 Transitional//EN&&&html&&&&head&&&&&&title&欢迎&/title&&&meta http-equiv=&pragma& content=&no-cache&&&&meta http-equiv=&cache-control& content=&no-cache&&&&meta http-equiv=&expires& content=&0&&&&&&&meta http-equiv=&keywords& content=&keyword1,keyword2,keyword3&&&&meta http-equiv=&description& content=&This is my page&&&&!--&&link rel=&stylesheet& type=&text/css& href=&styles.css&&&--&&&&/head&&&&&body&&&&s:set value=&#session.userName& name=&userName&&/&&&&你好!&s:property value=&#userName&/&&&&/body&&/html&&login_error.jsp&%@ page language=&java& import=&java.util.*& pageEncoding=&UTF-8&%&&!DOCTYPE HTML PUBLIC &-//W3C//DTD HTML 4.01 Transitional//EN&&&html&&&&head&&&&&&title&登陆失败&/title&&&meta http-equiv=&pragma& content=&no-cache&&&&meta http-equiv=&cache-control& content=&no-cache&&&&meta http-equiv=&expires& content=&0&&&&&&&meta http-equiv=&keywords& content=&keyword1,keyword2,keyword3&&&&meta http-equiv=&description& content=&This is my page&&&&!--&&link rel=&stylesheet& type=&text/css& href=&styles.css&&&--&&&&/head&&&&&body&&&&&很抱歉!你的登陆失败了!请重新&a href=&login.jsp&&登陆&/a&&&&/body&&/html&login.jsp&%@ page language=&java& import=&java.util.*& pageEncoding=&utf-8&%&&%@ taglib uri=&/struts-tags& prefix=&s&&%&&%String path = request.getContextPath();String basePath = request.getScheme()+&://&+request.getServerName()+&:&+request.getServerPort()+path+&/&;%&&!DOCTYPE HTML PUBLIC &-//W3C//DTD HTML 4.01 Transitional//EN&&&html&&&&head&&&&&&base href=&&%=basePath%&&&&&&&&&&&title&struts 2应用&/title&&&meta http-equiv=&pragma& content=&no-cache&&&&meta http-equiv=&cache-control& content=&no-cache&&&&meta http-equiv=&expires& content=&0&&&&&&&meta http-equiv=&keywords& content=&keyword1,keyword2,keyword3&&&&meta http-equiv=&description& content=&This is my page&&&&!--&&link rel=&stylesheet& type=&text/css& href=&styles.css&&&--&&&&/head&&&&body&&&&&&s:form& action=&user!loginOther& method=&post&&&红色部分,你如果想调用userAction中的loginOther方法而不想调用execute方法,&直接通过!+方法名即可,那你就不用再设置struts.xml中注释掉的部分了,这样可以不产生太多的action&s:textfield name=&userName& label=&请输入姓名&&&&/s:textfield&&&s:textfield name=&password& label=&请输入密码&&&/s:textfield&&&s:submit value=&提交&&&/s:submit&&&/s:form&&&&/body&&/html&&&Action Wildcard(Action 通配符)配置:&&&&&package name=&actions& extends=&struts-default& namespace=&/actions&&&&&&&&&&&action name=&Student*& class=&com.bjsxt.struts2.action.StudentAction& method=&{1}&&&&&&&&&&&&&&&result&/Student{1}_success.jsp&/result&&&&&&&&&&/action&&&&&&&&&&&&&&&&&action name=&*_*& class=&com.bjsxt.struts2.action.{1}Action& method=&{2}&&&&&&&&&&&&&&&result&/{1}_{2}_success.jsp&/result&&&&&&&&&&&&&&!--&{0}_success.jsp --&&&&&&&&&&/action&&/package&{1}、{2}表示第一第二个占位符*为通配符通过action name的通配匹配,获得占位符,可以使用占位符放在result和method、class中替代匹配的字符。总结:使用通配符,将配置量降到最低。&a href=&&%=context %&/actions/Studentadd&&添加学生&/a&&a href=&&%=context %&/actions/Studentdelete&&删除学生&/a&不过,一定要遵守&约定优于配置&的原则。&a href=&&%=context %&/actions/Teacher_add&&添加老师&/a&&a href=&&%=context %&/actions/Teacher_delete&&删除老师&/a&&a href=&&%=context %&/actions/Course_add&&添加课程&/a&&a href=&&%=context %&/actions/Course_delete&&删除课程&/a&&&&接收参数值1、使用action属性接收参数只需在action加入getter/setter方法,如参数name=a,接受到参数必须有getName/setName方法。&链接:&a href=&user/user!add?name=a&age=8&&public class UserAction extends ActionSupport {&&&&&& private S&&&&&&&&& public String add()&{&&&&&&& System.out.println(&name=&&+ name);&&&&&&& System.out.println(&age=&&+ age);&&&&&&& return SUCCESS;&&&&}&&& public String getName()&{&&&&&&&&&&&}&&& public void setName(String name)&{&&&&&&& this.name =&&&&}&&& public int getAge()&{&&&&&&&&&&&}&&& public void setAge(int age)&{&&&&&&& this.age =&&&&}}2、使用Domain Model接收参数将之前的属性放入到POJO ,并设置属性的setter/getter方法链接:使用Domain Model接收参数&a href=&user/user!add?user.name=a&user.age=8&&添加用户&/a&public class UserAction extends ActionSupport {&&&&&& private U&&&&//private UserDTO userDTO;&&& public String add()&{&&&&&&& System.out.println(&name=&&+ user.getName());&&&&&&& System.out.println(&age=&&+ user.getAge());&&&&&&& return SUCCESS;&&&&}&&& public User getUser()&{&&&&&&&&&&&}&&& public void setUser(User user)&{&&&&&&& this.user =&&&&}&&&}public class User {&&& private S&&&&&& public String getName()&{&&&&&&&&&&&}&&& public void setName(String name)&{&&&&&&& this.name =&&&&}&&& public int getAge()&{&&&&&&&&&&&}&&& public void setAge(int age)&{&&&&&&& this.age =&&&&}}3、使用ModelDriven接收参数Action实现ModelDriven接口,实现getModel()方法。这样user需要自己new出来,getModel返回user。链接:使用ModelDriven接收参数&a href=&user/user!add?name=a&age=8&&添加用户&/a&public class UserAction extends ActionSupport implements ModelDriven&User&&{&&&&&& private User user = new User();&&&&&& public String add()&{&&&&&&& System.out.println(&name=&&+ user.getName());&&&&&&& System.out.println(&age=&&+ user.getAge());&&&&&&& return SUCCESS;&&&&}&&&&@Override&&& public User getModel()&{&&&&&&&&&&&}}&字符编码配置:&constant name=&struts.i18n.encoding& value=&GBK&&/&&&!-- internationalization --&在struts2.1.6中不起作用,属于bug,在struts2.1.7中修改。解决方案:修改web.xml 中:&&&filter&&&&&&&&filter-name&struts2&/filter-name&&&&&&&&!-- struts2.1中使用filter --&&!--&filter-class&org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&/filter-class&--&&&&&&&&!-- struts2.0中使用的filter --&&filter-class&org.apache.struts2.dispatcher.FilterDispatcher&/filter-class&&&&/filter&&&&=============================================================Struts2一个Action内包含多个请求处理方法的处理(三种方式)Struts1提供了DispatchAction,从而允许一个Action内包含多个请求处理方法。Struts2也提供了类似的功能。处理方式主要有以下三种方式:1.1.&动态方法调用:DMI:Dynamic Method Invocation 动态方法调用。动态方法调用是指:表单元素的action不直接等于某个Action的名字,而是以如下形式来指定对应的动作名:&form method=&post& action=&userOpt!login.action&&则用户的请求将提交到名为”userOpt”的Action实例,Action实例将调用名为”login”方法来处理请求。同时login方法的签名也是跟execute()一样,即为public String login() throws Exception。注意:要使用动态方法调用,必须设置Struts2允许动态方法调用,通过设置struts.enable.DynamicMethodInvocation常量来完成,该常量属性的默认值是true。1.1.1.&&&&示例:修改用户登录验证示例,多增加一个注册用户功能。1.&&&&修改Action类:package org.qiujy.web.struts2.import com.opensymphony.xwork2.ActionCimport com.opensymphony.xwork2.ActionS&publicclass LoginAction extends ActionSupport{private String userNprivate Sprivate S&//结果信息属性public String getMsg()&{&&&&&&}&publicvoid setMsg(String msg)&{&&&&&& this.msg =}&public String getUserName()&{&&&&&& returnuserN}&publicvoid setUserName(String userName)&{&&&&&& this.userName = userN}&public String getPassword()&{&&&&&&}&publicvoid setPassword(String password)&{&&&&&& this.password =}public String login() throws Exception{&&&&&& if(&test&.equals(this.userName)&&&&&test&.equals(this.password)){&&&&&&&& msg =&&登录成功,欢迎&&+ this.userN&&&&&&&&&//获取ActionContext实例,通过它来访问Servlet API&&&&&&&& ActionContext context = ActionContext.getContext();&&&&&&&&&//看session中是否已经存放了用户名,如果存放了:说明已经登录了;//否则说明是第一次登录成功&&&&&&&& if(null != context.getSession().get(&uName&)){&&&&&&&&&&& msg = this.userName +&&:你已经登录过了!!!&;&&&&&&&&&}else{&&&&&&&&&&& context.getSession().put(&uName&, this.userName);&&&&&&&&&}&&&&&&&&&&&&&&& returnthis.SUCCESS;&&&&&&&}else{&&&&&&&& msg =&&登录失败,用户名或密码错&;&&&&&&&& returnthis.ERROR;&&&&&&&}}public String regist() throws Exception{&&&&&&&//将用户名,密码添加到数据库中&&&&&&&//...&&&&&& msg =&&注册成功。&;&&&&&& returnthis.SUCCESS;}}2.&&& struts.xml文件:没有什么变化,跟以前一样配置&!DOCTYPE struts PUBLIC&&&&&&&&-//Apache Software Foundation//DTD Struts Configuration 2.0//EN&&&&&&&&&&&&struts&&package name=&my& extends=&struts-default& namespace=&/manage&&&!--&定义处理请求URL为login.action的Action --&&&&&&&&&action name=&userOpt& class=&org.qiujy.web.struts2.action.LoginAction&&&&&&&&&&!--&定义处理结果字符串和资源之间的映射关系&--&&&&&&&&&&&result name=&success&&/success.jsp&/result&&&&&&&&&&&result name=&error&&/error.jsp&/result&&&&&&&&&/action&&/package&&/struts&3.&&&&页面:index.jsp&%@ page language=&java& pageEncoding=&UTF-8&%&&html&&head&&title&用户登录页面&/title&&/head&&body&&&&&h2&用户入口&/h2&&&&&hr&&form action=&manage/userOpt!login.action& method=&post&&&table border=&1&&&&&&&&&tr&&&&&&&&&&&td&用户名:&/td&&&&&&&&&&&td&&input type=&text& name=&userName&/&&/td&&&&&&&&/tr&&&&&&&&tr&&&&&&&&&&&td&密码:&/td&&&&&&&&&&&td&&input type=&password& name=&password&/&&/td&&&&&&&&/tr&&&&&&&&tr&&&&&&&&&&&td colspan=&2&&&&&&&&&&&&&&&&&&&input type=&submit& value=&&确定&&/&&&&&&&&&&&/td&&&&&&&&/tr&&/table&&/form&&/body&&/html&regist.jsp&%@ page language=&java& pageEncoding=&UTF-8&%&&html&&head&&title&用户注册页面&/title&&/head&&body&&&&&h2&用户注册&/h2&&&&&hr&&form action=&manage/userOpt!regist.action& method=&post&&&table border=&1&&&&&&&&&tr&&&&&&&&&&&td&用户名:&/td&&&&&&&&&&&td&&input type=&text& name=&userName&/&&/td&&&&&&&&/tr&&&&&&&&tr&&&&&&&&&&&td&密码:&/td&&&&&&&&&&&td&&input type=&password& name=&password&/&&/td&&&&&&&&/tr&&&&&&&&tr&&&&&&&&&&&td colspan=&2&&&&&&&&&&&&&&&&&&&input type=&submit& value=&&注册&&/&&&&&&&&&&&/td&&&&&&&&/tr&&/table&&/form&&/body&&/html&1.2.&为Action配置method属性:将Action类中的每一个处理方法都定义成一个逻辑Action方法。&!DOCTYPE struts PUBLIC&&&&&&&&-//Apache Software Foundation//DTD Struts Configuration 2.0//EN&&&&&&&&&&&&struts&&package name=&my& extends=&struts-default& namespace=&/manage&&&&&&&&&&action name=&userLogin& class=&org.qiujy.web.struts2.action.LoginAction& method=&login&&&&&&&&&&&&result name=&success&&/success.jsp&/result&&&&&&&&&&&result name=&error&&/error.jsp&/result&&&&&&&&&/action&&&&&&&&&&&&&&action name=&userRegist& class=&org.qiujy.web.struts2.action.LoginAction& method=&regist&&&&&&&&&&&&result name=&success&&/success.jsp&/result&&&&&&&&&&&result name=&error&&/error.jsp&/result&&&&&&&&&/action&&/package&&/struts&如上,把LoginAction中的login和regist方法都配置成逻辑Action。要调用login方法,则相应的把index.jsp中表单元素的action设置为&manage/userLogin.action&;要调用regist方法,把regist.jsp中表单元素的action设置为&manage/userRegist.action&。1.3.&使用通配符映射(wildcard mappings)方式:在struts.xml文件中配置&action…&元素时,它的name、class、method属性都可支持通配符,这种通配符的方式是另一种形式的动态方法调用。当我们使用通配符定义Action的name属性时,相当于用一个元素action定义了多个逻辑Action:&action name=&user_*&class=&org.qiujy.web.struts2.action.UserAction& method=&{1}&&&&&&&&&&&&result name=&success&&/success.jsp&/result&&&&&&&&&&&result name=&error&&/error.jsp&/result&&&&&&&&&/action&如上,&action name=”user_*”&定义一系列请求URL是user_*.action模式的逻辑Action。同时method属性值为一个表达式{1},表示它的值是name属性值中第一个*的值。例如:用户请求URL为user_login.action时,将调用到UserAction类的login方法;用户请求URL为user_regist.action时,将调用到UserAction类的regist方法。---------------------------=========================--------------------------------------& Struts2中路径问题是一个棘手的问题,初学时经常被路径问题搞得很烦,通过网上查找资料和自己实战中遇到的问题今天来对Struts2中的路径问题来一个总结,当然可能不会很完整,不过后续会进行补充:1.& Struts2 一个要匹配路径的地方就是在处理完请求之后对页面进行分发的时候,也就是 result 元素里面的内容。假设项目名为Struts2&在地址栏中访问action时URL基本是以 http://localhost:8080/Struts 开头比如&action name=&home&class=&test.HomeAction& namespace=&/&&&&&&&&&&result name=&success&&要访问的jsp页面/result&&/action&这里有两种方式来写要访问的jsp页面,一种加“/”,另一种是不加“/”。1)jsp页面写成/Pages/path.jsp,那么就会从项目的根路径中开始找也就是,也就是Struts所在的根目录,在一层一层的下去找。2)jsp页面写成Pages/path.jsp,那么就会从当前路径开始找(注意当前路径是指当前访问者请求的目录),在这个例子中的我们是通过请求action,进而间接访问到jsp文件的,所以当前路径应该就是action所在的路径,在本例中也就是http://localhost:8080/Struts,从这里可以看到当前路径就是根路径,所以两种方式都可以访问到jsp页面,如果当前路径不是根路径那么情况就不同了。&总结:为了不出错,建议加上“/”。&&2.&在页面中涉及到匹配路径的问题,在这里我们要弄清楚一个小知识点:在jsp页面中“/”指的是整个站点根路径也就是这里的“http://localhost:8080/”,而不是webapps所在的根路径。在页面中涉及到的路径问题,看似很复杂,但是解决起来很简单。就是统一用绝对路径,在jsp文件中可以这样写来统一路径:&%StringcontextPath=request.getContextPath();StringbasePath=requset.getScheme()+&://&+requset.getServerName()+&:&+request.getServerPort()+path+&/&;%&&在&head&&/head&中写成这样&baseherf=&&%=basePath&&&这说明在该页面中的所有路径都是于项目的WebRoot为相对路径,如项目的WebRoot下的Images/xxx.jpg ,在页面中就直接这样访问。在页面中的路径问题看似很复杂,但是解决起来相当的简单。注意:路径最后有“/”。比如在地址栏中输入http://localhost:8080/Struts2/path/path.action访问到了my.jsp在my.jsp的页面中有这样的一个链接:& ahref=&index.jsp&&并且两者在同一个目录下,按道理说直接点就可以访问的,但是事实上访问不到,地址栏中变成http://localhost:8080/Struts2/path/index.jsp,为什么为变成这样呢?因为:在my.jsp页面里它不会去看jsp的真正路径在哪里,它只会去看这个jsp映射到我们的服务器的URL地址。所以访问就不成功。&&&&总之,用了struts2来实现跳转的话想对的就是地址栏中action的访问地址,是以这个地址为标准的。这里强调一下Html代码&&&base href=”&%=basePath%&”/&&&&&这个意思是指这个jsp页面里所有的&a href=“”/&连接都会在前面加上basePath,不仅仅是这对于&head&&/head&中的:Html代码&&&link rel=&stylesheet& href=&style/css/index.css& type=&text/css&&&&&&&&&&&&&& media=&screen& charset=&utf-8&&/&&&&script src=&style/js/jquery.js& type=&text/javascript&&&/script&&&&也是起作用的。&&&&&我在网上看到有个使用这样解决的,这里也记录一下:Java代码&&结构:&&&&& WebRoot &&&&&|&&&&&& common &&&&&&|&&&&&&& css &&&&&&&|&&&&&&&&&&&& common.css &&&&&&&&&&|js&&&&&&&&&&&&&|common.js&&&&&&&&&&&link rel=&stylesheet& type=&text/css&&&&&&&&&&&&&& href=&&c:url value='/common/css/common.css'&/&&&/&&&&&&&&&&&&&&script language=&javascript& type=&text/javascript&&&&&&&&&&&&&& src=&&c:url value='/common/js/common.js'/&&&&/script&&&&&然后在jsp 页面中用&c:url&的方式导入css&就永远没有存在跳转后css&无效了,同理js&也一样&&=========================================================用Java开发Web应用时,无论是Jsp页面、Servlet或是web.xml配置文件中都涉及到路径的问题,而这又是初学者较容易混淆的地方,往往不知道如何写路径。其实服务器端和客户端在处理路径的方式上不一致,因此需要根据不同的情况写出正确的路径。下面通过例子来说明。&&&假设Web应用road中,应用的根路径下有一个dir1文件夹和dir2文件夹。c.jsp在dir1中,a.jsp和b.jsp在dir2中。Web应用的结构如图所示。&&&&&&&+ root&&&&&&&&&&&-dir1&&&&&&&&&&&&&& c.jsp&&&&&&&&&&&-dir2&&&&&&&&&&&&&& a.jsp&&&&&&&&&&&&&& b.jspJSP页面中正确的路径表示假设在a.jsp页面中有两个链接,分别链接到b.jsp和c.jsp页面。直接写路径表示和页面在同一个文件夹下面,如&a href=&b.jsp&&b.jsp&/a&&../&表示当前文件夹的上一级文件夹(相对路径),如:&&&&&&a href=&../dir2/b.jsp&&b.jsp&/a&,&&&&&&a href=&../dir1/c.jsp&&c.jsp&/a&&/&表示 http://机器IP:8080(绝对路径),如:&&&&&&a href=&/road/dir2/b.jsp&&b.jsp&/a&&&&&&&a href=&/road/dir1/c.jsp&&c.jsp&/a&Servlet中正确的路径表示转发请求时:&/&表示“http://服务器IP:8080/Web应用名”,例如:&&& String forward =&&/dir1/c.jsp&;&&& RequestDispatcher rd = request.getQRequestDispatcher(forward);重定向时:“/”&&表示“http://机器IP:8080”,而通过request.getContextPath()得到的是:“http://机器IP:8080/Web应用名”,例如:&&&& String str =& request.getContextPath();&&&& response.sendRedirect(str +&&/dir1/c.jsp&);配置文件web.xml中&& url-mapping中,&/&表示“http://IP地址:8080/Web应用名”××总结××在浏览器端:“/”表示的是一台WEB服务器,“http://机器IP:8080”在服务器端(请求转发):“/”表示的是一个WEB服务器端的应用,“http://机器IP:8080/Web应用”在服务器端(重定向):“/”表示的是一个WEB服务器,“http://机器IP:8080”=========================================================要在/jsp/index.jsp文件使用图片,如何计算相对路径?&经过Servlet,struts转发后又?&&&&&&&&&&目录结构:&&&&&&------------------------------------------------------------------------------&第一种情况&:直接访问JSP文件URL是&http://localhost/Context path/jsp/index.jsp&要在index.jsp引用go.gif文件:1、使用决对路径&img src='&%=request.getContextPath()&%&/images/go.gif'/&浏览器寻找方式:&域名+/Context path/images/go.gif &&,可找到。&&&2、使用相对路径&img src='../images/go.gif'/&浏览器寻找方式:通过地址栏分析,index.jsp所在目录(jsp)的上一层目录(WebRoot)下的images/go.gif文件&。&&3、使用base href写&%=request.getContextPath()&%&太麻烦,可以在每一个jsp文件顶部加入以下代码&% String path = request.getContextPath(); String basePath = request.getScheme()+&://&+request.getServerName()+&:&+request.getServerPort()+path+&/&;&%&&&base href=&&%=basePath%&&&&&&&img src='images/go.gif'/&浏览器寻找方式: basePath的值再加上images/go.gif,可找到。&&------------------------------------------------------------------------------第二种情况: servlet转发到jsp&1、使用相对路径&URL是http://localhost/Context path/servlet_2 &&(转发到/jsp/index.jsp)&错误:根据/jsp/index.jsp路径计算,得到&&img src='../images/go.gif'/&&&正确:&img src='images/go.gif'/&&原因:index.jsp是保存在服务器端的/jsp/index.jsp目录下面,但通过转发后浏览器并不知道/jsp/目录的存在,因为地址栏中没有体现出来。所以服务器端/jsp/目录并不会对相对路径产生影响浏览器寻找方式:通过地址栏分析http://localhost/Context path/servlet_2 ,相对于servlet_2所在目录(/)下面找到images/go.gif文件&&2、使用相对路径URL是http://localhost/Context path/servlet/ser/ser/servlet_1 (转发到/jsp/index.jsp)&“/servlet/ser/ser/servlet_1 是在web.xml文件配置的&错误:根据/jsp/index.jsp路径计算,得到&&img src='../images/go.gif'/&&正确:&&img src='../../../images/go.gif'/&&原因:index.jsp是保存在服务器端的/jsp/index.jsp目录下面,但通过转发后浏览器并不知道/jsp/目录的存在,因为地址栏中没有体现出来。所以服务器端/jsp/目录并不会对相对路径产生影响浏览器寻找方式:通过地址栏分析http://localhost/Context path/servlet/ser/ser/servlet_1,相对于servlet_1所在目录(ser)的上一层目录的上一层目录的上一层目录(/)下的images/go.gif文件&&&3、使用决对路径&img src='&%=request.getContextPath()&%&/images/go.gif'/&&&------------------------------------------------------------------------------&总结:相对路径是由浏览器通过地址栏分析出来的,与服务器端文件的存放路径没有关系,由其是使用Servlet,struts转发到某jsp文件后,某jsp在服务器端存放的位置是/a/b/c/d/f/g.jsp ,&但经过Servlet,struts转发后,浏览器的地址栏可不一定是/a/b/c/d/f/这样的层次。所以相对路径的计算以浏览器地址栏为准。原创地址:&&&struts2中可以使用命名空间,来保证浏览器地址栏中的目录层次与服务器端目录层次的一致性,这样程序员通过服务器端的目录层次计算相对路径,在浏览器中也是正常的。但我们理解了原理,就算不使用命名空间,自己也有强大的控制力。&
转载了此文字
很喜欢此文字
很喜欢此文字
转载了此文字

我要回帖

更多关于 struts action 的文章

 

随机推荐