struts2自带项目showcase的fileupload与filedownload功能学习笔记

[size=x-large]struts2自带项目showcase的fileupload功能学习笔记[/size]
学习Struts2的自带项目showcase的fileupload功能。把我认为的一些疑问点写下来。

[size=large]第一[/size]、我们先理解下struts-xml中的package的namespace属性,这个属性自然是为了在不同的命名空间中可以使用同名的action。我们先看下面的代码:
<package name ="upload" extends="struts-default" namespace ="/fileupload">
<action name ="upload" class = "fileupload.FileuploadAction" method ="input">
<result name ="success">upload.jsp</result>
</action>
</package>
这个意思就是针对所有的/fileupload/upload.do的请求,我们使用fileupload.FileuploadAction去处理它,如果针对SUCCESS的返回,我们使用/fileupload/upload.jsp去响应它。这里的/fileupload/upload.do虽然是绝对路径,但是这里的绝对路径是针对应用的根而不是服务器的根。即/fileupload/upload.jsp都是根据你的项目名,如果你的项目名为MyStruts的话那么实际上就为http://localhost:端口号//MyStruts/fileupload/upload.jsp 同样web.xml中的

 <servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>

其中的url-pattern中的/test也是根据你的项目为根目录,而不是整个服务器为根目录
注意这里就要区别于
<a href ="value">
的用法了。比如绝对 URL href="http://www.example.com/index.htm"),绝对URL,就是在前面不加上工程名。直接就是主机名,而相对 URL - 指向站点内的某个文件(href="index.htm")也就是以当前的页面前缀为前缀。即浏览器会从当前文档的 URL 中提取相应的元素来填写相对 URL 中的空白,
比如在我们的主也页面http://localhost:8080/MyWebAssignment/上有
<form action = "test"></form>
那么这个form就是发往
http://localhost:8080/MyWebAssignment/test
如果为
<form action = "/test"></form>[/code
http://localhost:8080/test

还要注意basePath的问题[code="java"]<base href="<%=basePath%>">
也就是使用basePath来填写相对路径的空白
[quote]<base> 标签为页面上的所有链接规定默认地址或默认目标。
通常情况下,浏览器会从当前文档的 URL 中提取相应的元素来填写相对 URL 中的空白。
使用 <base> 标签可以改变这一点。浏览器随后将不再使用当前文档的 URL,而使用指定的基本 URL (就是basePath)来解析所有的相对 URL。这其中包括 <a>、<img>、<link>、<form> 标签中的 URL。 [/quote] 比如
<a href = "ui/test4.jsp">test4</a>
就是使用basePath加在ui/test4.jsp前面,这里就是http://localhost:8080/MyServletTest1/ui/test4.jsp,而如果我们去除jsp页面中的base标签,那么这个url就为http://localhost:8080/MyServletTest1/test/ui/test4.jsp
此外还要注意:如果是这样的:
<result>/empmanager/listEmployees.jsp</result>
就不需要使用namspace所设置的路径为前缀了,因为它本身就是相对于项目名的绝对路径。
此外还有一个东西需要注意,就是我们的请求也必须加上
namespace="fileupload"
。比如在form标签中加上namespace属性,或是在一个struts的url标签中加上namespace属性。
<s:url action = "upload" var ="upload" namespace ="/fileupload"/>

[size=medium]1.[/size]如果在请求中不写namespace的话类似:
<a href="<s:url action="edit"><s:param name="skillName" value="name"/></s:url>"><s:property value="name"/></a>
就会使用默认路径
[quote]namespace from where tag is used[/quote] 即就会产生一个把当前的action请求替换为这个新的这个action请求的目录。比如在点击之前,这个目录为:
http://localhost:8080/MyStrutsShowcase/skill/list.action,而点击这后就变为:http://localhost:8080/MyStrutsShowcase/skill/edit.action?skillName=WW-JUN即把list.action替换为新的edit.action再加上相应的参数。
[size=medium]2.[/size]如果在struts.xml中不写namespace的话,默认就为/,即主机名:端口号/项目名/ 为默认初始的路径。
[quote]The default namespace is "" - an empty string. The default namespace is used as a "catch-all" namespace. [/quote]
[size=large]
第二[/size]、action的相应属性如何得到页面字段对应的属性。这是通过拦截器把Action的属性值设置进去的。在“defaultStack”interceptor-stack中有个“param”拦截器:com.opensymphony.xwork2.interceptor.ParametersInterceptor,在这个拦截器的方法:
public String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (!(action instanceof NoParameters)) {
ActionContext ac = invocation.getInvocationContext();
final Map<String, Object> parameters = retrieveParameters(ac);

if (LOG.isDebugEnabled()) {
LOG.debug("Setting params " + getParameterLogMap(parameters));
}

if (parameters != null) {
Map<String, Object> contextMap = ac.getContextMap();
try {
ReflectionContextState.setCreatingNullObjects(contextMap, true);
ReflectionContextState.setDenyMethodExecution(contextMap, true);
ReflectionContextState.setReportingConversionErrors(contextMap, true);

ValueStack stack = ac.getValueStack();
setParameters(action, stack, parameters);
} finally {
ReflectionContextState.setCreatingNullObjects(contextMap, false);
ReflectionContextState.setDenyMethodExecution(contextMap, false);
ReflectionContextState.setReportingConversionErrors(contextMap, false);
}
}
}
return invocation.invoke();
}

在setParameters方法里有具体设置属性的操作,你可以看到这么一段:
...
try {
newStack.setValue(name, value);
} catch (RuntimeException e) {
...
}
...


[size=x-large]struts2自带项目showcase的filedownload功能学习笔记[/size]
链接到filedownload的相应页面和上传功能类似,这里不再赘述,但是相应的配置文件需要分析下:
<package name ="download" extends="struts-default" namespace="/filedownload">
<default-action-ref name ="download"/>
<action name ="download" class ="filedownload.FiledownloadAction" >
<param name="inputPath">/images/struts.gif</param>
<result name ="success" type ="stream">
<param name ="contentType">image/gif</param>
<param name ="inputName">inputStream</param>
<param name ="contentDisposition">filename ="struts.gif"</param>
<param name ="bufferSize">4096</param>
</result>
</action>
</package>
这里要注意:
<param name="inputPath">/images/struts.gif</param>
这个我的理解就是对于download的请求,我们在调用FiledownloadAction这个类时传入inputPath=/images/struts.gif这个参数.
[size=large]第二、[/size]我们要注意,如果我们使用stream这种一般用于文件下载的返回类型的话,我们要在相应的Action类中增加getInputSteam方法:
public InputStream getInputStream(){
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}
这里我们再来看下:
[quote]getServletContext

public static javax.servlet.ServletContext getServletContext()

Gets the servlet context.

Returns:
the servlet context.[/quote]
而getResourceAsStream:[quote]Returns the resource located at the named path as an InputStream object.
[/quote]
[quote]Parameters:
path - a String specifying the path to the resource [/quote]

[size=large]第三、[/size]我们注意下这个stream的返回类型及其所需的参数
stream:直接向响应中发送原始数据,通常在用户下载时使 用,contentType指定流的类型,默认为text/plain,contentLength以byte计算流的长 度,contentDisposition指定文件的位置,通常为filename=”文件的位置”,input指定InputStream的名字,例 如:imageStream,bufferSize指定缓冲区大小,默认为1024字节;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值