BOS物流管理系统-第五天
Posted beyondcj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BOS物流管理系统-第五天相关的知识,希望对你有一定的参考价值。
BOS物流管理系统-第五天-定区管理-WebServcie远程调用
主要内容:
-
分区设置—导出(分区条件查询后的结果导出为Excel—POI生成Excel和文件下载)
-
定区管理---定区添加(定区关联分区和取派员,easyUi相关的注意的地方)
-
定区管理-分页条件查询(复习—form表单json转换,Spring Data Specification )
-
定区管理—定区关联客户(模拟系统间:bos和crm(Customer Relational Managerment)的远程调用—WebService CXF、Hessian\\crm系统架构+SSH,json的解析:Gson技术)
学习目标:
-
Excel文件的导出;
-
定区的管理的业务--复杂业务的编写
-
远程调用,接口数据的调用(搭环境)
-
GSON的使用
-
分区设置—导出分区数据
目标:分区条件查询后的结果导出为Excel,备份出来。
需求分析:
导出的数据不仅是本页的,而是符合条件的全部数据。
因此:程序中list查询,需要带业务条件,但不能带分页条件!
【回顾】
文件下载的要求:
-
JavaWeb:
-
客户端同步方式提交请求,不能使用Ajax方式,否则浏览器无法捕捉到下载,无法出现下载框。
-
服务器需要向响应中放入文件的输出流,并且一般需要指定Content-Type(内容类型)和Content-Disposition(附件打开方式和附件的名字)。
-
-
Struts2:
-
客户端同步方式提交请求。
-
使用Stream类型的结果集,该结果集封装了一些操作,比如将输出流放入响应中,但也需要设置Content-Type和Content-Disposition。
-
开发步骤:
-
客户端页码代码
因为查询的form中的表单缓存了查询条件,因此,直接提交该表单,进行导出数据。
使用分区查询form提交给下载服务器端路径:
给导出按钮添加表单提交事件:
-
服务端代码
SubareaAction:
//导出分区文件 @Action(value="subarea_exportData") public String exportData() throws IOException{ //获取查询条件Specification对象 Specification<Subarea> specification = getSubareaSpecification(); //调用业务层查询数据(无需分页) List<Subarea> subareaList= subareaService.findSubareaListByspecification(specification);
//使用POI,将数据转换生成Excel(.xls格式) //开发过程 //1.创建一个新的空白工作簿Excel HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); //2.在工作簿中创建一个新的工作表 HSSFSheet sheet = hssfWorkbook.createSheet();//可以匿名,也可以有名字 //3.在工作表中创建第一行,作为标题行 HSSFRow headRow = sheet.createRow(0); //给标题行的每一格写入数据 headRow.createCell(0).setCellValue("分区编号"); headRow.createCell(1).setCellValue("区域编码"); headRow.createCell(2).setCellValue("关键字"); headRow.createCell(3).setCellValue("起始号"); headRow.createCell(4).setCellValue("结束号"); headRow.createCell(5).setCellValue("单双号"); headRow.createCell(6).setCellValue("位置信息"); //4.在工作表中写入其他数据行,每一个分区对应一行数据 for (Subarea subarea : subareaList) { HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum()+1);//从第二行开始写 dataRow.createCell(0).setCellValue(subarea.getId()); dataRow.createCell(1).setCellValue(subarea.getRegion().getId()); dataRow.createCell(2).setCellValue(subarea.getAddresskey()); dataRow.createCell(3).setCellValue(subarea.getStartnum()); dataRow.createCell(4).setCellValue(subarea.getEndnum()); dataRow.createCell(5).setCellValue(subarea.getSingle().toString());//Character不识别 dataRow.createCell(6).setCellValue(subarea.getPosition()); }
//设置客户端浏览器用于识别附件的两个参数Content-Type和Content-Disposition //文件名 String downFilename="分区数据.xls"; //获取文件的MIME类型: String contentType=ServletActionContext.getServletContext().getMimeType(downFilename); //将MIME类型放入响应 ServletActionContext.getResponse().setContentType(contentType); //浏览器类型 String agent = ServletActionContext.getRequest().getHeader("user-agent"); //附件名编码,解决中文乱码问题 downFilename = FileUtils.encodeDownloadFilename(downFilename, agent); //获取附件的名字和下载方式 String contentDisposition="attachment;filename="+downFilename; //将附件名字和下载方式放入响应头信息中 ServletActionContext.getResponse().setHeader("Content-Disposition", contentDisposition);
//将Excel的文件流写入到客户端响应中 hssfWorkbook.write(ServletActionContext.getResponse().getOutputStream());
return NONE; } |
SubareaService:
/** * 根据条件查询分区列表 * @param specification * @return */ public List<Subarea> findSubareaListByspecification(Specification<Subarea> specification); |
SubareaServiceImpl:
public List<Subarea> findSubareaListByspecification(Specification<Subarea> specification) { return subareaDAO.findAll(specification); } |
提示:
可将Specification对象的获取抽取出来一个单独的方法,可简化代码。
-
定区管理—定区添加
需求分析:
了解什么是定区?取派员固定的配送区域,该区域需要配置管理。它是动态可调整的。
定区是分区的集合,实际业务中,定区需要指定多名取派员负责,(需开发取派员排班功能、收派时间管理)。
这里简化业务,一个定区关联了一个取派员。
目标:
定区添加,主要是关联 取派员和分区。即定区是由哪个取派员负责的,该定区包含哪几个分区。
-
取派员下来列表的数据填充
目标:显示取派员的下拉列表:
开发步骤:
-
客户端页码
注意:从业务角度上说,要显示的快递员必须是未作废的、正常的。
-
服务端代码
StaffAction:
//异步请求没有删除标记的派送员列表 @Action(value="staff_listNoDelAjax") public String listNoDelAjax(){ //调用业务层 List<Staff> staffList= staffService.findStaffListForNoDel(); //压入栈顶 ActionContext.getContext().getValueStack().push(staffList); return JSON; } |
StaffService:
/** * 查询所有没有作废的员工 * @return */ public List<Staff> findStaffListForNoDel(); |
StaffServiceImpl:
public List<Staff> findStaffListForNoDel() { //调用dao层查询,查询未作废的派送员 return staffDAO.findByDeltag(\'0\'); } |
StaffDAO:
//根据删除标志来查询派送员 //使用了自动参数查找的查询策略,即根据删除标记来查询派送员列表 List<Staff> findByDeltag(Character deltag); |
-
未分配的分区列表的表格(Datagrid)显示
目标:在添加页面显示未分配的分区列表,用户关联分区。
-
客户端代码
-
服务端代码
SubareaAction:
//查询所有没有定区关联的分区列表 @Action(value="subarea_listNoDecidedZone") public String listNoDecidedZone(){ //调用业务层查询 List<Subarea> subareaList= subareaService.findSubareaListForNoDecidedZone(); //压入栈顶 ActionContext.getContext().getValueStack().push(subareaList); return JSON; } |
SubareaService:
/** * 查询出所有没有被定区关联的分区 * @return */ public List<Subarea> findSubareaListForNoDecidedZone(); |
SubareaServiceImpl:
public List<Subarea> findSubareaListForNoDecidedZone() { //调用dao层 return subareaDAO.findByDecidedZoneIsNull(); // return subareaDAO.findSubareaListForNoDecidedZone(); } |
SubareaDAO:
//查询定区是空的分区:方法一:使用Spring Data JPA的属性表达式 List<Subarea> findByDecidedZoneIsNull();
//查询定区是空的分区:方法二:直接写语句 @Query("from Subarea where decidedZone is null")//注意面向对象的写法 List<Subarea> findSubareaListForNoDecidedZone(); |
-
定区添加的实现
目标:保存定区数据,在分区表中使用外键关联定区。
-
解决请求中定区编号和分区编号的参数名称冲突的问题
1)客户端代码
decidedzone.jsp:
点击添加form中save按钮,提交form (验证功能) //保存定区 $("save").click(){ //表单校验 if($("#decidedZoneForm").form("validate")){ $("#decidedZoneForm").submit();//提交表单保存数据 } }; |
2)服务端代码:
PO采用手动指定id的方式:
【思考】
多个分区如何封装?
分区的datagrid勾选后,在表单中提交什么?
问题: 分区datagrid 勾选 分区编号,会不会随form 提交 ???
相当于页面上有:很多checkbox
发现提交的是表单复选框的字段。
但请求参数中定区编号和分区编号的参数名称会发生冲突:
分区编号提交时 也为id 和定区编号冲突
解决方案:
1)修改datagrid的复选框的field的名字:
-
服务端代码
修改服务器返回json,含有subareaId , 修改Subarea
Subarea:
//添加含有subareaId的getter方法,为了前端json显示该参数 @Transient public String getSubareaId(){ return id; } |
测试:
-
添加定区的服务端代码实现
服务端代码如下:
DecidedZoneAction:
//定区的Action @ParentPackage("basic-bos") @Namespace("/") @Controller @Scope("prototype") public class DecidedZoneAction extends BaseAction<DecidedZone>{ //属性驱动接受关联的分区 private String[] subareaId; public void setSubareaId(String[] subareaId) { this.subareaId = subareaId; }
//注入service @Autowired private DecideZoneService decideZoneService;
@Action(value="decideZone_save",results={@Result(name=SUCCESS,location="/WEB-INF/pages/base/decidedzone.jsp")}) public String save(){ //调用业务层保存定区 decideZoneService.saveDecideZone(model,subareaId); return SUCCESS; }
} |
DecidedZoneService:
//定区业务层接口 public interface DecideZoneService {
/** * 保存定区,并关联分区 * @param decidedZone * @param subareaIdArray */ public void saveDecideZone(DecidedZone decidedZone, String[] subareaIdArray);
} |
DecidedZoneServiceImpl:
//定区业务层实现类 @Service @Transactional public class DecideZoneServiceImpl implements DecideZoneService{ //注入dao @Autowired private DecideZoneDAO decideZoneDAO; @Autowired private SubareaDAO subareaDAO;
public void saveDecideZone(DecidedZone decidedZone, String[] subareaIdArray) { //保存定区(可能bug) &n 以上是关于BOS物流管理系统-第五天的主要内容,如果未能解决你的问题,请参考以下文章 |