跟着汤阳光同志做一个OA系统(十三):文件上传下载细节、乱码解决

35 篇文章 0 订阅
29 篇文章 0 订阅

增加ModelDriven支持

publicabstract  class BaseActionWithModelDriven<T>extends BaseAction implements ModelDriven<T> {

 

ModelDriven支持

    protected T model = null;

    public BaseActionWithModelDriven(){

       ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();

       Class<T> clazz = (Class<T>)pt.getActualTypeArguments()[0];

       try {

           model = clazz.newInstance();

       } catch (Exception e) {

           thrownew RuntimeException(e);

       }

    }

    public T getModel() {

       returnmodel;

    }

   

}

 

 

 

 

Service中因为我们不能直接增删改jbpm的数据,所以并不需要继承DaoSupport

@Service

@Transactional

publicclass ProcessDefinitionServiceImpl implements ProcessDefinitionService {

 

    @Resource

    private ProcessEngine processEngine;

 

查询最新的所有流程定义

public List<ProcessDefinition> findAllLatestVersions() {

       // 1,查询所有的流程定义列表,把最新的版本都排到最后面

       List<ProcessDefinition> all = processEngine.getRepositoryService()// 

              .createProcessDefinitionQuery()//

              .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//

              .list();

 

       // 2,过滤出所有最新的版本

       Map<String, ProcessDefinition> map = new HashMap<String,ProcessDefinition>();

       for (ProcessDefinition pd : all) {

           map.put(pd.getKey(), pd);

       }

 

       returnnew ArrayList<ProcessDefinition>(map.values());

    }

 

根据key删除所有

/** 删除 */

    public String delete() throws Exception {

       // key = newString(key.getBytes("iso8859-1"), "utf-8");

       key = URLDecoder.decode(key, "utf-8"); // 自己再进行一次URL解码

       processDefinitionService.deleteByKey(key);

       return"toList";

    }

 

publicvoid deleteByKey(String key) {

       // 1,查询出指定key的所有版本的流程定义

       List<ProcessDefinition> list = processEngine.getRepositoryService()//

              .createProcessDefinitionQuery()//

              .processDefinitionKey(key)//

              .list();

 

       // 2,循环删除

       for (ProcessDefinition pd : list) {

           processEngine.getRepositoryService().deleteDeploymentCascade(pd.getDeploymentId());

       }

    }

 

 

部署流程定义

/** 部署 */

    public String add() throws Exception {

       ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(upload));//upload是上传来的文件

       try {

           processDefinitionService.deploy(zipInputStream);

       } finally {

           zipInputStream.close();

       }

       return"toList";

    }

 

publicvoid deploy(ZipInputStream zipInputStream) {

       processEngine.getRepositoryService()//

              .createDeployment()//

              .addResourcesFromZipInputStream(zipInputStream)//

              .deploy();

    }

 

 

/** 查看流程图,其实是下载功能 */

    public String downloadProcessImage() throws Exception {

       //用于流程图查看提供的流程定义ID

id = URLDecoder.decode(id, "utf-8"); // 自己再进行一次URL解码

       inputStream = //根据下载的配置要求提供一个流

processDefinitionService.getProcessImageResourceAsStream(id);

       return"downloadProcessImage";

    }

 

public InputStream getProcessImageResourceAsStream(StringprocessDefinitionId) {

       // 根据id取出对应的流程定义对象

       ProcessDefinition pd = processEngine.getRepositoryService()//

              .createProcessDefinitionQuery()//

              .processDefinitionId(processDefinitionId)//

              .uniqueResult();

 

       // 返回图片资源

       returnprocessEngine.getRepositoryService().getResourceAsStream(pd.getDeploymentId(),pd.getImageResourceName());

    }



JSP页面中写的js代码传递参数的时候注意,如果是字符串必须加上单引号,因为EL表达式在服务端执行,解析后如果没加单引号就形成如下,这样显然执行会出错

<ahref="javascript: showProcessImage(${id})">查看流程图</a>

<ahref="javascript:showProcessImage(hjdf)">查看流程图</a>

修改成如下之后就能正确执行了

<ahref="javascript:showProcessImage('${id}')">查看流程图</a>

<ahref="javascript:showProcessImage('hjdf')">查看流程图</a>

 

打开新窗口显示图片

<scripttype="text/javascript">

        functionshowProcessImage( pdId ){

        // alert("原文:" + pdId);

       

        pdId = encodeURI(pdId);

        // alert("第一次URL编码:" + pdId);

 

        pdId = encodeURI(pdId);

        // alert("第二次URL编码:" + pdId);

       

            var url ="processDefinitionAction_downloadProcessImage.action?id=" + pdId +"&t=" + new Date();//对于这种js提交的请求最好加上时间戳,防止不刷新

            window.showModalDialog(url,null,"dialogHeight:500px;dialogWidth:600px;resizable:yes");

        }

    </script>

 

 

<s:formaction="processDefinitionAction_add"enctype="multipart/form-data">//默认就是post

<form>默认是get请求

 

 

 

<s:aaction="processDefinition_delete"onclick="return delConfirm()">

                     <s:paramname="key"value="%{@java.net.URLEncoder@encode(key, 'utf-8')}"></s:param>

                     删除

                  </s:a>

像上面这种在OGNL中调用了静态方法,必须在struts.xml中配置

<!-- OGNL中可以使用静态的方法 -->

    <constantname="struts.ognl.allowStaticMethodAccess"value="true"/>

 

 

限制选择的文件的扩展名,详细的使用见jQuery-validator的文档

<inputtype="file"name="upload"class="InputStyle {required:true,accept:'.zip'}"style="width:450px;"/>

 

 

 

 

 

乱码问题的解决

 

表单采用Post方式提交,解决乱码的方法为:

         request.setCharacterEncoding( myEncoding );

 

表单采用Get方式提交,解决乱码的方法为:

         方式一:

                   key = newString(key.getBytes("iso8859-1"), "utf-8");

         方式二:

                   修改server.xml:  URIEncoding="utf-8"

         方式三(不依赖Tomcat的配置,那么你的信息必须是英文的,通过转换嘛。推荐

另外Base64的思想,都可以把二进制转换成字符):

                   浏览器中两次URL编码。

                   服务器中自己再做一次URL解码。

 

<s:param自己本身有一次编码

<s:aaction="processDefinitionAction_delete" οnclick="returndelConfirm()">

         <s:param name="key" value="%{@java.net.URLEncoder@encode(key,'utf-8')}"></s:param>    

         删除

</s:a>

 

 

 

/**

     * 保存上传的文件,并返回文件在服务端的真实存储路径

     *

     * @param upload

     * @return

     */

    protected String saveUploadFile(File upload) {

       SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");

       // >>获取路径

       String basePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/upload_files");

       String subPath = sdf.format(new Date());

       // >>如果文件夹不存在,就创建

       File dir = new File(basePath + subPath);

       if (!dir.exists()) {

           dir.mkdirs(); // 递归的创建不存在的文件夹

       }

       // >>拼接路径

       String path = basePath + subPath + UUID.randomUUID().toString();

       // >>移动文件

       upload.renameTo(new File(path));// 如果目标文件夹不存在,或是目标文件已存在,就会不成功,返回false,但不报错。

       return path;

    }

 

<!-- 下载专用的结果配置 -->

           <resultname="download"type="stream">

              <paramname="contentType">application/octet-stream</param>

              <paramname="inputName">inputStream</param>

              <paramname="contentDisposition">attachment;filename="${#fileName}.doc"</param>

           </result>

/** 下载 */

    public String download()throws Exception {

       //准备下载的资源

       ApplicationTemplate applicationTemplate =applicationTemplateService.getById(model.getId());

       inputStream =new FileInputStream(applicationTemplate.getPath());

 

       //准备文件名(解决乱码问题)

       String fileName = URLEncoder.encode(applicationTemplate.getName(),"utf-8");// 方法一

       // String fileName = newString(applicationTemplate.getName().getBytes("gbk"),"iso8859-1"); //方法二

       ActionContext.getContext().put("fileName", fileName);

 

       return"download";

    }

 

    // ---

 

    public InputStream getInputStream() {

       returninputStream;

    }

 

// 服务器端的文件存储方案:

 

方案一:存到数据库中(BLOB)。

 

 

方案二:存到服务器的某文件夹中(推荐)。

         需要String型的path(相对于服务器的一个相对路径)。

 

 

问题:

         文件重名:使用UUID做为文件名,如果需要原始的文件名,则可以存到数据库中(用一个列)。

         文件过多:分文件夹存放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值