Struts2数据处理与上传

Struts2数据处理与上传

Struts2配置

Struts2开发的几种方式

  • 实现action接口,这个接口定义了一些常量和一个execute方法,重写excute方法即可
public interface Action {
public static final String SUCCESS = "success";
public static final String NONE = "none";
    public static final String ERROR = "error";
    public static final String INPUT = "input";
    public static final String LOGIN = "login";
    public String execute() throws Exception;
}
  • 不继承,不实现任何接口
public class IndexAction{
    public String execute(){
        return "success"
    }
}
  • 继承ActionSupport(推荐使用),该方法继承了action方法

访问通配符

通配符:在struts中,可以用*与{1}优化配置

<package name="config" namespace="/" extends="struts-default" abstract="false">
		<!-- 使用通配符配置多个action -->
		<action name="user_*" class="cn.csx.config.UserAction" method="{1}">
			<result name="{1}">/{1}.jsp</result>
		</action>
</package>

struts路径匹配原则

<package name="config" namespace="/user" extends="struts-default" abstract="false">
		<!-- 使用通配符配置多个action -->
		<action name="user_*" class="cn.csx.config.UserAction" method="{1}">
			<result name="{1}">/{1}.jsp</result>
		</action>
</package>

struts常量

  • Struts默认访问前缀是:

    • Struct1:是*.do
    • Struct2:是*.action
  • 修改默认访问前缀

struts的访问前缀在哪定义

image

image

2、 在struts.xml修改

<!-- 修改struts默认访问后缀 -->
	<constant name="struts.action.extension" value="action,do,,"></constant>
	<!--Value=”action,do,”  访问后缀 action,do,或者没有后缀-->
  • 常用的一些常量
指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    自定义后缀修改常量
    <constant name="struts.action.extension" value="do"/>
    设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 
    <constant name="struts.serve.static.browserCache" value="false"/>
    当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 
    <constant name="struts.configuration.xml.reload" value="true"/>
    开发模式下使用,这样可以打印出更详细的错误信息 
    <constant name="struts.devMode" value="true" />
    默认的视图主题 
    <constant name="struts.ui.theme" value="simple" />
    与spring集成时,指定由spring负责action对象的创建 
    <constant name="struts.objectFactory" value="spring" />
    该属性设置Struts2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性
    为 false
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
    上传文件的大小限制
    <constant name="struts.multipart.maxSize" value=“10701096"/>
  • 动态方法调用:actionName+!方法即为动态方法调用
<constant name="struts.enable.DynamicMethodInvocation" value="true "/>
 <!-- 动态方法调用: http://locahost:8080/struts02/user!login 
		<action name="user" class="cn.csx.b_config2.UserAction">
			<result name="success">/index.jsp</result>			
		</action>

全局配置和默认配置

  • 全局视图配置(global在action前面,不然会报错)

返回结果标记success对应的页面再当前action中没有配置,所以会去找全局配置有是否有success标记对应的页面

<!-- 配置全局跳转视图 -->
		<global-results>
			<result name="success">/index.jsp</result>
		</global-results>
  • 默认配置
!-- 配置各项默认值 -->
		 <!-- 
		 	 name  只配置了访问路径名称
		 	 class 默认执行的action在struts-default有配置
		 	 		<default-class-ref class="com.opensymphony.xwork2.ActionSupport"/>
		 	 method  默认为execute
		 	 默认的方法execute返回值为success,对应的页面去全局视图找。

Struts核心操作

数据处理的几种方式

  1. 直接获取servlet 核心类ServletActionContext
  2. 通过ActionContext获取不同的(代表request,application,session),从map中获取
@Override
	public String execute() throws Exception {
		
		// 1. 请求数据封装; 2. 调用Service处理业务逻辑,拿到结果数据
		
		// 3. 数据保存到域中
		
		/*
		 * 
		// Struts中对数据操作,方式1: 直接拿到ServletApi, 执行操作
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpSession session = request.getSession();
		ServletContext application = ServletActionContext.getServletContext();
		// 操作
		request.setAttribute("request_data", "request_data1");
		session.setAttribute("session_data", "session_data1");
		application.setAttribute("application_data", "application_data1");
		*/
		
		
		// 【推荐:解耦的方式实现对数据的操作】
		// Struts中对数据操作,方式2: 通过ActionContext类 
		ActionContext ac = ActionContext.getContext();
		// 得到Struts对HttpServletRequest对象进行了封装,封装为一个map
		// 拿到表示request对象的map
	 	Map<String,Object> request =  ac.getContextMap(); 
	 	// 拿到表示session对象的map
	 	Map<String, Object> session = ac.getSession();
	 	// 拿到表示servletContext对象的map
	 	Map<String, Object> application = ac.getApplication();
	 	
	 	// 数据
	 	request.put("request_data", "request_data1_actionContext");
		session.put("session_data", "session_data1_actionContext");
		application.put("application_data", "application_data1_actionContext");
		
		return SUCCESS;
	}
  1. 实现接口的方式(RequestAware, SessionAware, ApplicationAware)
public class DataAction extends ActionSupport implements RequestAware, SessionAware, ApplicationAware{
	
	private Map<String, Object> request;
	private Map<String, Object> session;
	private Map<String, Object> application;
	
	// struts运行时候,会把代表request的map对象注入
	@Override
	public void setRequest(Map<String, Object> request) {
		this.request = request;
	}
	
	// 注入session
	@Override
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}
	
	// 注入application
	@Override
	public void setApplication(Map<String, Object> application) {
		this.application = application;
	}


	@Override
	public String execute() throws Exception {
		
	 	// 数据
	 	request.put("request_data", "request_data1_actionAware");
		session.put("session_data", "session_data1_actionAware");
		application.put("application_data", "application_data1_actionAware");
//		
		return SUCCESS;
	}

}

请求数据自动封装

  • 实现原理

参数拦截器

<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

  • 方式一:jsp表单数据填充到action 的属性
  • 方式二:jsp表单数据自动填充到对象中的属性
public class UserAction {
	
	 // 对象类型,一定给get方法
	private User user; 
	public void setUser(User user) {
		this.user = user;
	}
	public User getUser() {
		return user;
	}

	// 处理注册请求
	public String register() {
		System.out.println(user.getName());
		System.out.println(user.getPwd());
		System.out.println(user.getAge());
		System.out.println(user.getBirth());
		return "success";
	}
}

	<form action="${pageContext.request.contextPath}/user_register.action" method="post">
  		用户名:<input type="text" name="user.name"><br/>
  		密码:<input type="text" name="user.pwd"><br/>
  		年龄:<input type="text" name="user.age"><br/>
  		生日:<input type="text" name="user.birth"><br/>
  		
  		<input type="submit" value="注册">
  	</form>

类型转换

Struts对应jsp表单提交的数据会自动转换为action中的属性

对于基本数据类型和日期类型会自动转换

但是日期类型只支持yyyy-MM-dd格式

其他格式,需要自定义类型转换器

  • 局部类型转换器
  • 全局类型转换器
  • Struts类型转换器
    • TypeConverter 转换器接口
      • DefaultTypeConverter 默认类型转换器接口
        • StrutsTypeConverter 用户编写的类型转换器,继承它即可
  1. 自定义转换器继承StrutsTypeConverter
  2. 重写convertFromString和convertToString方法
  3. 注册转换器
    1. 在Action所在包中建立 Action名-conversion.properties,如

      java.util.Date= cn.csx.converter.DateConverter

    2. 在3.1文件中添加以下数据 需要转换的字段名=自定义转换器类的权限定名 birthday=cn.csx.convertor.DateTypeConvertor

public class MyConverter extends StrutsTypeConverter {

	// 新需求: 要求项目中要支持的格式,如: yyyy-MM-dd/yyyyMMdd/yyyy年MM月dd日..

	// 先定义项目中支持的转换的格式
	DateFormat[] df = { new SimpleDateFormat("yyyy-MM-dd"),
			new SimpleDateFormat("yyyyMMdd"),
			new SimpleDateFormat("yyyy年MM月dd日") };

	/**
	 * 把String转换为指定的类型 【String To Date】
	 * 
	 * @param context
	 *            当前上下文环境
	 * @param values
	 *            jsp表单提交的字符串的值
	 * @param toClass
	 *            要转换为的目标类型
	 */
	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {

		// 判断: 内容不能为空
		if (values == null || values.length == 0) {
			return null;
		}
		// 判断类型必须为Date
		if (Date.class != toClass) {
			return null;
		}
		
		// 迭代:转换失败继续下一个格式的转换; 转换成功就直接返回
		for (int i=0; i<df.length; i++) {
			try {
				return df[i].parse(values[0]);
			} catch (ParseException e) {
				continue;
			}
		}
		return null;
	}

	@Override
	public String convertToString(Map context, Object o) {
		return null;
	}

}

文件上传

Struts提交的文件上传组件来上传文件

前台:

  1. 提交方式:post
  2. 表单类型 multipart/form-data
  3. input=file

后台:

  • Apache提供的FileUpload组件
  • 核心类:
    • FileItemFactory FileItem的工厂
    • ServletFileUpload servlet中文件上传的核心类
    • FileItem 封装了上传表单的数据

Struts的文件上传

Struts的文件上传拦截器帮我们完成了功能

<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>

实例

public class FileUpload extends ActionSupport {

	// 对应表单:<input type="file" name="file1">
	private File file1; 
	// 文件名
	private String file1FileName;
	// 文件的类型(MIME)
	private String file1ContentType;
	public void setFile1(File file1) {
		this.file1 = file1;
	}
	public void setFile1FileName(String file1FileName) {
		this.file1FileName = file1FileName;
	}
	public void setFile1ContentType(String file1ContentType) {
		this.file1ContentType = file1ContentType;
	}
	
	
	@Override
	public String execute() throws Exception {
		/******拿到上传的文件,进行处理******/
		// 把文件上传到upload目录
		
		// 获取上传的目录路径
		String path = ServletActionContext.getServletContext().getRealPath("/upload");
		// 创建目标文件对象
		File destFile = new File(path,file1FileName);
		// 把上传的文件,拷贝到目标文件中
		FileUtils.copyFile(file1, destFile);
		
		return SUCCESS;
	}
}

文件上传细节

文件大小限制

默认是2M,通过常量修改

修改最大大小是30M

<constant name="struts.multipart.maxSize" value=“10701096"/>

限制文件上传类型 拦截器注入参数,解决问题

<!-- 注意: action 的名称不能用关键字"fileUpload" -->
		<action name="fileUploadAction" class="cn.csx.e_fileupload.FileUpload">
		
			<!-- 限制运行上传的文件的类型 -->
			<interceptor-ref name="defaultStack">
				
				<!-- 限制运行的文件的扩展名 -->
				<param name="fileUpload.allowedExtensions">txt,jpg,jar</param>
				
				<!-- 限制运行的类型   【与上面同时使用,取交集】
				<param name="fileUpload.allowedTypes">text/plain</param>
				-->
				
			</interceptor-ref>
			
			<result name="success">/e/success.jsp</result>
			
			<!-- 配置错误视图 -->
			<result name="input">/e/error.jsp</result>
		</action>

文件下载

  • 文件下载:两种方式
    • 方式一:通过response对象向浏览器写入字节数据,设置下载响应头
    • 方式二:struts方式
public class DownAction extends ActionSupport {
	
	
	/*************1. 显示所有要下载文件的列表*********************/
	public String list() throws Exception {
		
		//得到upload目录路径
		String path = ServletActionContext.getServletContext().getRealPath("/upload");
		// 目录对象
		File file  = new File(path);
		// 得到所有要下载的文件的文件名
		String[] fileNames =  file.list();
		// 保存
		ActionContext ac = ActionContext.getContext();
		// 得到代表requestmap (第二种方式)
		Map<String,Object> request= (Map<String, Object>) ac.get("request");
		request.put("fileNames", fileNames);
		return "list";
	}
	
	
	/*************2. 文件下载*********************/
	
	// 1. 获取要下载的文件的文件名
	private String fileName;
	public void setFileName(String fileName) {
		// 处理传入的参数中问题(get提交)
		try {
			fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		// 把处理好的文件名,赋值
		this.fileName = fileName;
	}
	
	//2. 下载提交的业务方法 (在struts.xml中配置返回stream)
	public String down() throws Exception {
		return "download";
	}
	
	// 3. 返回文件流的方法
	public InputStream getAttrInputStream(){
		return ServletActionContext.getServletContext().getResourceAsStream("/upload/" + fileName);
	}
	
	// 4. 下载显示的文件名(浏览器显示的文件名)
	public String getDownFileName() {
		// 需要进行中文编码
		try {
			fileName = URLEncoder.encode(fileName, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		return fileName;
	}

	
}




	<action name="down_*" class="cn.csx.e_fileupload.DownAction" method="{1}">
			<!-- 列表展示 -->
			<result name="list">/e/list.jsp</result>
			<!-- 下载操作 -->
			<result name="download" type="stream">
			
				<!-- 运行下载的文件的类型:指定为所有的二进制文件类型 -->
			   <param name="contentType">application/octet-stream</param>
			   
			   <!-- 对应的是Action中属性: 返回流的属性【其实就是getAttrInputStream()】 -->
			   <param name="inputName">attrInputStream</param>
			   
			   <!-- 下载头,包括:浏览器显示的文件名 -->
			   <param name="contentDisposition">attachment;filename=${downFileName}</param>
			 
			 	<!-- 缓冲区大小设置 -->
			   <param name="bufferSize">1024</param>
			</result>
		</action>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值