OA (ssh) 基本实现(poi 生成 Excel , struts2动态下载 mysql数据
oa项目学习笔记: 里程碑1:2009-12-11 搭配环境ssh 1.创建web工程 2.将工程上下文加到server.xml文件中。也就是为项目提供上下文的重加载与访问。 Context path=/oa docBase=D:/Program Files/MyEclipse 6.0/eclipse/workspace/oa/WebRoot reloadable=true/
oa项目学习笔记:
里程碑1: 2009-12-11
搭配环境ssh
1.创建web工程
2.将工程上下文加到server.xml文件中。也就是为项目提供上下文的重加载与访问。
3.首先将hibernate3.1的包到oa工程中。
4.然后将spring2.0的包到oa工程中。
5.接着将struts2的包到oa工程中。
6.将struts2注入web环境,配置struts2的映射,设置访问路径模式。并为ssh框架整合提供上下文加载监听。
7.添加业务逻辑,与数据库的链接。
里程碑2: 2009-12-11
1.添加struts.xml国际化。
2.添加服务接口及实现。在进行List泛型强转时,在方法前添加@SuppressWarnings("unchecked"),去掉警告。
3.方法:我们可以点击一下某个接口的方法,可以直接进入他的实现类,而不是接口类。
里程碑3: 2009-12-11
解决乱码问题的最佳解决方式:
1.将数据库的编码方式设成UTF-8。
2.struts2默认的编码方式为UTF-8。即struts.i18n.encoding=UTF-8。
3.将jsp页面的编码方式也设为UTF-8。
这样就省去了每次将字符编码转化或过滤的方式了:
1.使用字符编码的过滤器.
1.1 自定义实现过滤器的方式设置字符编码
web.xml 中配置
package com.cs.tb.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 用于设置 HTTP 请求字符编码的过滤器,通过过滤器参数encoding指明使用何种字符编码,用于处理Html Form请求参数的中文问题
*/
public class CharacterEncodingFilter implements Filter {
private FilterConfig filterConfig;
private String encoding = "";
public void destroy() {
filterConfig = null;
encoding = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if(encoding != null){
request.setCharacterEncoding(encoding);//设置字符编码
chain.doFilter(request, response);//将请求和响应转向下一个链接
}
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = this.filterConfig.getInitParameter("encoding");// 获得web.xml文件中的过滤器中的初始化值encoding
}
}
1.2 使用ActionContextCleanUp
web.xml中配置
org.apache.struts2.dispatcher.ActionContextCleanUp
2.request.setCharacterEncoding("UTF-8");
3.str = new String(str.getBytes("ISO8859-1"),"UTF-8");
里程碑4: 2009-12-12
使用ognl获得request中的属性对象或者传递值。如#request.list 或者 %{#u.id}
“#”主要有三种用途:
访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性: 名称 作用 例子
parameters 包含当前HTTP请求参数的Map #parameters.id[0]作用相当于request.getParameter("id")
request 包含当前HttpServletRequest的属性(attribute)的Map #request.userName相当于request.getAttribute("userName")
session 包含当前HttpSession的属性(attribute)的Map #session.userName相当于session.getAttribute("userName")
application 包含当前应用的ServletContext的属性(attribute)的Map #application.userName相当于application.getAttribute("userName")
attr 用于按request > session > application顺序访问其属性(attribute) #attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止
用于过滤和投影(projecting)集合,如books.{?#this.price 构造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。
“%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值
“$”有两个主要的用途
用于在国际化资源文件中,引用OGNL表达式,例子请参考《在Struts 2.0中国际化(i18n)您的应用程序》
在Struts 2配置文件中,引用OGNL表达式
里程碑5: 2009-12-12
使用在Spring创建action时默认为单例,而当我们每次刷新或者调用的时候,都放到我们的fielderror的map中所以显示的错误会越来越多。
而将action的请求范围是prototype的方式时,Spring动态创建action实例。
我们可以在action里实现validate方法,获得FieldErrors,并打印,就知道其中的原因了。
@Override
@SuppressWarnings("unchecked")
public void validate() {
Map map = this.getFieldErrors();
Set set = map.keySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(map.get(iterator.next()));
}
}
添加模块驱动的验证框架,验证方式为visitor,这样就可以在bean对象这添加bean对象的属性验证信息。
但是其中还有参数的设置,
context 也就是bean对象验证的中间的那个别名,
appendPrefix 附加前缀 作为输出错误信息的头
message 就是附加的信息
里程碑6: 2009-12-13
使用 poi 导出 Excel 文件
使用HSSF horrible spread sheet format 讨厌的电子表格格式 动态生成 Excel 文件
其中的关键就是文件的如何获得,一般我们都知道文件是以流的形式,进行写入写出的。
那么在这里,同样也是,提供一个InputStream getDownloadFile()是struts2支持下载的方式。
具体呈现在struts.xml文件中,
application/vnd.ms-excel//这是默认的,潜在的。用以指明文件下载的内容格式.
attachment;filename="AllUser.xls"//filename 这是默认的,潜在的。用以指明文件下载的文件名.
//tachment指明文件是作为附件,支持下载,而不是直接打开查看的。
downloadFile//接收流并支持下载的输入名
只要在页面提供一个超链接的标记就可以动态下载了。
里程碑7: 2009-12-14
struts2动态下载框架的使用,文件下载的文件处理方式。
我们下载生成的临时文件定死的名称,但是在读写的时候会导致数据不一致。
所以我们必须做有效的处理:生成随机的文件名便是一种好的方式。
RandomStringUtils.randomAlphanumeric(length);这是Spring自动提供的。用以生成动态的随机的字符串。
在这里我们可以借鉴下这个思想,也就是注册码的生成。
里程碑8: 2009-12-15
将生成的临时文件删除策略:
1.通过HSSF的工作簿写入到临时文件中.但是要考虑删除问题.
1.1将生成的临时文件定死的名称,但是在读写的时候会导致数据不一致。
1.2将生成的临时文件取个随机文件名。
1.3那么接下来时删除文件的问题了,我们可以通过一个线程睡眠多长时间,然后进行删除。
1.4但是服务器一旦关闭,我们又得重新考虑问题了。
1.5所以我们得创建一个servlet其提供给系统启动时调用。则:不生成servlet映射文件,同时设置load-on-startup删除未删除的文件。
2.通过获得HSSF的getBytes()字节数组.也就是不生成临时文件,直接从内存中获得,但是生成的xls文件数据会丢失一部分.这是getBytes()造成的。
3.通过HSSF的工作簿在内存中的数据写入到一个字节数组输出流获得字节数组。
之后导入到输入流中,struts提供动态下载的框架中。供他人下载。
怎么在getInputStream方法中直接使用file.delete()方法不管用.
我的理解是:该临时文件就在一定的系统引用里,除非调用线程删除临时文件,否则删除失败.
也就是说:在多线程环境中,可能会有其他线程操作此文件,所以删不掉,注意程序中操作文件的同步问题。
总结:多线程时候 清理一下思路和环境 保证该文件没有被其他线程 以及系统调用 建议检查一下程序流程 看看该文件是否在其他部位被引用。
有错误的地方,有更好的想法,请指正!!!O(∩_∩)O~
文件下载的地方 已上传!!!!