`

struts操作集锦

阅读更多
Struts2中获取HttpServletRequest,HttpSession
在没有使用Struts2之前,都习惯使用HttpServletRequest和HttpSession对象来操作相关参数,下面介绍一下在Struts2中访问隐藏的HttpServletRequest和HttpSession的两种方法:

1.非Ioc方式

这种方式主要是利用了com.opensymphony.xwork2.ActionContext类以及ora.apache.struts2.ServletActionContext类,具体的方法如下所示。

获得request对象:

1).HttpServletRequest request = ServletActionContext.getRequest ();

2).ActionContext ct= ActionContext.getContext();

   HttpServletRequest request=

(HttpServletRequest)ct.get(ServletActionContext.HTTP_REQUEST);

获得session对象:

在Struts2中底层的session都被封装成了Map类型,我们称之为SessionMap,而平常我们所说的session则是指HttpSession对象,具体的获得方法如下所示。

1).Map session=ActionContext.getSession();

2).Map session=(Map)ActionContext.getContext().get(ActionContext.SESSION);

得到这个SessionMap之后我们就可以对session进行读写了,如果我们想得到原始的HttpSession可以首先得到HttpServletRequest对象,然后通过request.getSession()来取得原始的HttpSession对象。一般情况下SessionMap已经可以完成所有的工作,我们不必再去强行使用底层的session了。

文件上传的原理:

  表单元素的enctype属性指定的是表单数据的编码方式,该属性有3个值:

  1) application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的

值处理成URL编码方式。

  2) multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到

请求参数里。

  3) text/plain:这种方式主要适用于直接通过表单发送邮件的方式。

  文件上传是web应用经常用到的一个知识。原理是,通过为表单元素设置enctype=”multipart/form-data”属性,让表单提交的数据以二

进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。

  在Java领域中,有两个常用的文件上传项目:一个是Apache组织Jakarta的Common-FileUpload组件

(http://commons.apache.org/fileupload/),另一个是Oreilly组织的COS框架(http://www.servlets.com/cos/)。利用这两个框架都能很方便

的实现文件的上传。


==================================
Struts2上传文件


增加commons-fileupload-1.2.jar和commons-io-1.3.1.jar到lib

=====
 jsp
=====

form 的 enctype 设置为 multipart/form-data

 

==============
 UploadAction
==============
private String username;
private String password;
private File file;           // 对应文件域
private String fileFileName; // 前面的File属性的名字 + FileName(固定的)
private String fileContent;  // 前面的File属性的名字 + Content

//  setter...  getter...

String execute() throws Exception {

 InputStream is = new FileInputStream( file );

 String root = ServletActionContext.getRequest().getRealPath("/upload");

 File destFile = new File(root,this.getFileFileName());

 OutputStream os = new FileOutputStream( destFile );

 byte[] buffer = new byte[400];

 int length = 0;

 while( (length = is.read(buffer)) > 0 ) {

  os.write(buffer,0,length);
 }

 is.close();
 os.close();

 return SUCCESS;
}

=================
    中文问题
=================

不过我全部用UTF-8并未遇到中文问题

struts2-core包
struts-default.xml                      ----拦截器的设置
org.apache.struts2.default.properties   ----全局属性的设置

33行  strusts.i18n.encoding=UTF-8   默认UTF-8

可以在struts.xml下进行设置

<struts>
 设置字符集
 <constant name="struts.i18n.encoding" value="gbk"/>

 设置上传文件缓存
 <constant name="struts.multipart.saveDir" value="c:\"/> 
</struts>

其他属性
struts.multipart.parser=jakarta   struts2采用那种方式上传
                        pell
                        cos

struts.multipart.maxSize=2097152   默认上传文件最大的请求大小2M

struts.action.extension=action     整个url的后缀名

 


================
  上传多个文件
================

有两种方式:
1.数组
File[] file                文件
String[] fileFileName      文件名
String[] fileContentType   文件类型

2.集合
List<File>   file   
List<String> fileFileName
List<String> fileContentType

--------
action中:
--------
String execute() {

 for(int i = 0; i < file.size(); i++) {
  InputStream is = new FileInputStream(file.get(i));
  String root = ServletActionContext.getRequest().getRealPath("/upload");
  File destFile = new File(root,this.getFileFileName().get(i)); 
  ... 
 } 

 return SUCCESS;
}

------
jsp中:
------
多个file时,file的名字要一致,都要叫file,它会自动set到跟file名对应的List中去

<s:file name="file" />
<s:file name="file" />
<s:file name="file" />


========================
  上传任意个文件
========================

<td id="more">
 <input type="button" value="添加" onclick="addMore()" />
</td>

------
  JS:
------
funcation addMore() {

 var td = document.getElementById("more");

 //生成一个换行符
 var br = document.createElement("br");

 //创建一个input组件
 var input = document.createElement("input");
 var button = document.createElement("input");

 //指定类型 为 file 为文件上传
 input.type = "file";

 //指定组件的名字
 input.name = "file";

 button.type = "button";
 button.value = "删除";

 //为删除按钮注册一个事件 
 button.onclick = function() {
  //alert("删除按钮");

  //删除一行
  td.removeChild(br);
  td.removeChild(input);
  td.removeChild(button);
 }

 //将创建的组件加到<td>中
 td.appendChild(br);
 td.appendChild(input);
 td.appendChild(button);
}

 

=======================
     限制上传类型
=======================
org.apache.struts2.interceptor.FileUploadInterceptor类

Long maximumSize:最大上传大小---每一个文件的大小,不是总和
String allowedTypes:允许的类型

-------------
 struts.xml
-------------
<struts>
 <action ...>
  <result name="input">/upload.jsp</result>
  <result .../>
  
  加入一个上传文件的拦截器并设置其属性
  <interceptor-ref name="fileUpload">


   <param name="maximumSize">409600</param>   单个上传文件最大不能超过400K
   <param name="allowedTypes">...</param>     mime类型,多个用逗号分开


  </interceptor-ref>

  ** 加入默认的拦截器
  <interceptor-ref name="defaultStack" />
 </action>  
</struts>

注:后缀可以到tomcat\conf\web.xml中找<mime-type>中的字符串

 

--------------
  upload.jsp
--------------

  添加<s:fielderror />

----------------------
  更改显示的错误信息
----------------------

org.apache.struts2中  找到struts-messages.properties

-----------------------
上传文件类型不匹配
struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" {2}

-----------------------
上传文件大小超出规定
struts.messages.error.file.too.large=File too large: {0} "{1}" {2}

-----------------------
上传文件出错
struts.messages.error.uploading=Error uploading: {0}

创建一个全局的属性文件 /src/messages.properties

struts.messages.error.content.type.not.allowed=不支持上传该类型的文件
struts.messages.error.file.too.large=上传文件过大,请重试
struts.messages.error.uploading=上传文件时发生错误

---------
  国际化
---------
<constant name="struts.custom.i18n.resources" value="messages"/>

messages_en_US.properties
messages_zh_CN.properties

 


==============================
            下载
==============================

处理下载的类:org.apache.struts2.dispatcher.StreamResult

== 属性 ==

String contentType = "text/plain";       
String contentLength;
String contentDisposition = "inline";    
String inputName = "inputStream";        
InputStream inputStream;                
int bufferSize = 1024;                   

== 说明 == 

contentType 

内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片  

用来做动态文件下载的,事先并不知道未来的文件类型是什么,那么我们可以把它的值设置成为:application/octet-stream;charset=ISO8859-1 ,注意一定要加入charset,否则某些时候会导致下载的文件出错

inputName 

下载文件的来源流,对应着action类中某个类型为Inputstream的属性名,例如取值为inputStream的属性需要编写getInputStream()方法 

contentDisposition 

文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。取值为:attachment;filename="struts2.txt",表示文件下载的时候保存的名字应为struts2.txt。如果直接写filename="struts2.txt",那么默认情况是代表inline,浏览器会尝试自动打开它,等价于这样的写法:inline; filename="struts2.txt" 

bufferSize 

下载缓冲区的大小 

 # contentType属性和contentDisposition分别对应着HTTP响应中的头Content-Type和Content-disposition头。

   如:
     HTTP头内容: 

     HTTP/1.1 200 OK 
     Server: Apache-Coyote/1.1 
     Content-disposition: attachment;filename="struts2.txt" 
     Content-Type: text/plain 
     Transfer-Encoding: chunked 
     Date: Sun, 02 Mar 2008 02:58:25 GMT 

----------
  action
----------
Class DownloadAction extends ActionSupport {

 private String path;

 // setter... getter...

 //必须返回一个输入流,该流是让用户下载的
 public InputStream getDownloadFile() {
 
  //从某个文件获得流 --这里是获得项目root下upload下的文件

  //也可以 new FileInputStream("c:/test.text");
  return ServletActionContext.getServletContext().getResourceAsStream("/upload/struts2.ppt");
  
 }

 public String execute() throws Exception {

  return SUCCESS;
 }
}

-----------
struts.xml
-----------
 <action name="download" class="org.scorpio.jh.struts2.upload.action.DownloadAction">
  
   <!-- 依赖注入文件路径 -->
   <param name="path">/download/xhtml.txt</param>
   
   <!-- 设置结果类型为 流 -->
   <result name="success" type="stream">
    
    <!-- 设置内容类型 -->
    <param name="contentType">text/plain</param>
    
    <!-- 设置下载文件的名字  attachment:作为附件,filename=:指定下载文件名-->
    <param name="contentDisposition">attachment;filename="xhtml.txt"</param>
   
    <!-- 设置下载文件的输入流对应的方法 downloadFile对应DownloadAction中的getDownloadFile()-->
    <param name="inputName">downloadFile</param>
   
    <!-- 指定下载文件的缓冲大小 --> 
    <param name="bufferSize">4096</param>
   </result>
  </action>

 

==========================
  解决下载文件名中文问题
==========================

1.在下载action获取文件名的方法中先进行转码然后再返回

   path = new String( path.getBytes(), "ISO-8859-1" );


2.xml配置文件动态的获取path的值

   <param name="contentDisposition">attachment;filename="${path}"</param>

   ${path} 用于动态的获取所配置的action中path成员的值,相当于调用getPath()方法

-------
action
-------
private String path;
 
public String getPath() {
  
 try {               //转换成西欧字符集
  path = new String( path.getBytes(), "ISO-8859-1" );
 } catch (UnsupportedEncodingException e) {
  e.printStackTrace();
 } 
  
 return path;
}

public void setPath(String path) {
 this.path = path;
}

---------------
   struts.xml
---------------

<action name="download" class="org.scorpio.jh.struts2.upload.action.DownloadAction">
 
 <param name="path">/download/wmlscript实例.txt</param>

 <result name="success" type="stream">
  <param name="contentType">text/plain</param>

  <!-- 动态的获取 DownloadAction的path属性 -->
  <param name="contentDisposition">attachment;filename="${path}"</param>

  <param name="inputName">downloadFile</param>
  <param name="bufferSize">4096</param>
 </result>
</action>

 

=================
    安全隐患
=================

访问者如果精通Struts 2的话,它可能使用这样的带有表单参数的地址来访问:

http://localhost:8080/struts2hello/download3.action?inputPath=/WEB-INF/web.xml,这样的结果就是下载后的文件内容是您系统里面的web.xml的文件的源代码,甚至还可以用这种方式来下载任何其它JSP文件的源码。这对系统安全是个很大的威胁。作为一种变通的方法,读者最好是从数据库中进行路径配置,然后把Action类中的设置inputPath的方法统统去掉,简言之就是删除这个方法定义: 

public void setPath(String path) { 
 this.path = path; 
} 

而实际情况则应该成为 download.action?fileid=1 类似于这样的形式来进行。或者呢,读者可以在execute()方法中进行路径检查,如果发现有访问不属于download下面文件的代码,就一律拒绝,不给他们返回文件内容。例如,我们可以把刚才类中的execute()方法加以改进,成为这样: 

public String execute() throws Exception { 

// 文件下载目录路径
String downloadDir = ServletActionContext.getServletContext().getRealPath("/download"); 

// 文件下载路径
String downloadFile = ServletActionContext.getServletContext().getRealPath(inputPath); 

java.io.File file = new java.io.File(downloadFile); 

downloadFile = file.getCanonicalPath();// 真实文件路径,去掉里面的..等信息 

// 发现企图下载不在 /download 下的文件, 就显示空内容 
if(!downloadFile.startsWith(downloadDir)) { 
 return null; 
} 

return SUCCESS; 

} 

这时候如果访问者再企图下载web.xml的内容,它只能得到一个空白页,现在访问者只能下载位于/download目录下的文件

分享到:
评论

相关推荐

    简单struts对单表的操作

    在这个主题中,我们主要关注"简单Struts对单表的操作",包括数据的CRUD(创建、读取、更新和删除)操作以及基础的分页实现。 1. **Struts框架介绍** Struts框架是由Apache软件基金会维护的开源项目,它提供了一种...

    struts相关文档集锦

    - **Hibernate集成**:Struts可以与Hibernate ORM框架配合,方便地处理数据库操作。 - **Struts与AJAX**:Struts 2支持AJAX,可以创建异步交互的应用。 7. **学习资源** - 文档:官方文档、用户手册、教程等提供...

    Struts实现CRUD操作

    在本教程中,我们将探讨如何利用Struts实现CRUD(创建、读取、更新和删除)操作,这是一些基本但至关重要的数据库交互功能。 首先,理解Struts框架的核心组件至关重要。ActionServlet是Struts的入口点,它处理HTTP...

    struts1和struts2的区别

    - **Struts2**: 使用OGNL进行数据绑定,支持更高级的数据绑定操作。 #### 验证机制 - **Struts1**: 支持ActionForm的内置验证机制,并且可以通过Commons Validator进行扩展。 - **Struts2**: 提供了更强大的验证...

    Struts2与Struts1区别

    - Struts1 使用 JSTL 的 EL(Expression Language),而 Struts2 引入了自己的 OGNL(Object-Graph Navigation Language),提供了更强大的数据访问和操作能力,允许在视图层更自由地访问和操作模型数据。...

    Struts2.5操作JSON相关jar包

    本知识点主要围绕Struts2.5操作JSON的相关jar包进行详细介绍。 首先,`json包和struts2——json插件`这个文件很可能包含了Struts2的JSON插件,它是Struts2与JSON进行数据交换的核心组件。该插件允许我们在Action类...

    struts2+hibernate实现登录及增删改操作

    Struts2是一个基于MVC(Model-View-Controller)模式的框架,它提供了处理用户请求、控制应用流程的能力,而Hibernate则是一个对象关系映射(ORM)工具,用于简化数据库操作。 1. **Struts2框架**:Struts2是Apache...

    struts2的项目(多表操作)

    这个项目名为“struts2的项目(多表操作)”,显然它专注于使用Struts2来实现对多个数据库表的操作,包括数据的增删改查以及搜索功能。下面将详细解释相关知识点。 1. **Struts2框架**: Struts2是Apache软件基金...

    struts2jar包

    Action是业务逻辑的入口点,Result表示一个操作完成后转向的页面或结果。拦截器是Struts2的一大特色,可以实现如日志、权限检查、事务控制等功能。 总的来说,Struts2是一个功能强大且成熟的MVC框架,其jar包的引入...

    Struts2视频教程

    - **拦截器**:拦截器是Struts2的一个重要特性,可以在请求到达Action之前或之后执行特定的操作,如验证用户登录状态、日志记录等。 #### 四、Struts2进阶技巧 - **ModelDriven模式**:该模式允许Action实例共享同...

    struts2小程序 struts2代码

    这个“struts2小程序”很可能是开发者利用Struts2框架开发的一个小型项目,可能包含了基本的CRUD操作或其他特定功能。在描述中提到花费了3小时搭建,暗示这可能是一个简单的入门示例,用于学习或教学目的。 Struts2...

    struts2-scan_struts2-scan_struts2scan_scan_struts2漏洞_

    Struts2漏洞通常涉及到框架的核心组件,例如OGNL(Object-Graph Navigation Language)表达式,这是一种强大的语言,允许在运行时动态地操作对象属性。2017年,一个名为CVE-2017-9805的重大漏洞被发现,它允许远程...

    struts1和struts2区别

    - **Struts2**:Action不再直接依赖容器,测试可以独立进行,虽然仍能访问请求和响应,但通常不需直接操作。 4. **可测性**: - **Struts1**:由于Action与Servlet API紧密耦合,测试较为困难,需要使用如Struts ...

    struts1和struts2的jar包

    3. **Action**:实现了业务逻辑,是应用程序的核心部分,接收ActionForm的数据并执行相关操作。 4. **Tiles**:用于页面布局,允许开发者创建可重用的页面片段,提高了应用的可维护性。 **Struts2** Struts2在2007...

    传智播客struts2.1视频教程_介绍struts2及struts2开发环境的搭建

    Struts2.1是Apache软件基金会的一个开源框架,主要用于构建基于Java EE的Web应用程序。它在Struts1的基础上进行了很多改进,提供了更...记得结合实际操作,理论与实践相结合,这样才能更好地掌握Struts2框架的精髓。

    struts2的struts.properties配置文件详解

    1. struts.action.extension:这是Struts2用来确定是否将请求作为Struts操作的URL扩展名。例如,登录操作的URL可以是login.do,struts.action.extension设置为.do。 2. struts.configuration:这是Struts2的配置...

    Struts1万能文件操作组件

    本文将深入探讨“Struts1万能文件操作组件”,介绍其功能、使用方法以及如何在实际项目中应用。 文件操作是Web应用程序中的常见需求,包括文件的上传、下载、删除等。Struts1提供了名为File Operation Support(FOS...

    Struts2环境配置与基本操作演示

    接下来,我们来谈谈**OGNL**,它是Struts2中的表达式语言,用于访问和操作对象图。OGNL可以方便地在视图层和模型层之间传递数据。例如,你可以使用OGNL在JSP页面中直接访问Action类的属性,或者在Action类中设置请求...

    Struts1.2+IBatis操作数据库的案例

    结合这两个框架,开发者可以在Struts1.2的Action中调用iBatis的Mapper接口,执行数据库操作。例如,要实现"增、删、改、查"操作: 1. 增加(Insert):在iBatis的Mapper XML文件中编写INSERT SQL语句,然后在Action...

Global site tag (gtag.js) - Google Analytics