SSH综合项目实战(快递) -- day04 快递员分页查询、POI读取Excel、代码重构

一、快递员组合条件分页查询

1、在courier.html页面添加查询按钮



2、编写点击搜索按钮执行的j打开搜索窗口的 js


3、给搜索窗口中的提交按钮绑定事件

(1)、让datagrid从新加载数据的API


(2)、提供自定义方法,将表单的数据转换为json对象

	$.fn.serializeJson=function(){  
           var serializeObj={};  //定义一个json对象
           var array=this.serializeArray();   //通过js提供的serializeArray方法将表单中数据转换成json格式的数组:[{name:"a",value"1"},{name:"b",value"2"}],其中this代表当前表单对象
           var str=this.serialize();  
           $(array).each(function(){  //遍历json数组
               if(serializeObj[this.name]){  
                   if($.isArray(serializeObj[this.name])){  
                       serializeObj[this.name].push(this.value);  
                   }else{  
                       serializeObj[this.name]=[serializeObj[this.name],this.value];  
                   }  
               }else{  
                   serializeObj[this.name]=this.value;   
               }  
           });  
           return serializeObj;  //最终转换完成之后的json对象 [{"a":"1"},{"b":"2"}]
       }; 

(3)、绑定提交按钮事件的js代码


<script type="text/javascript">
		//为查询按钮绑定点击事件
		$(function(){
			//--------------------自定义的将表单中数据序列化为json对象的方法----------------------------
			$.fn.serializeJson=function(){  
		           var serializeObj={};  //定义一个json对象
		           var array=this.serializeArray();   //通过js提供的serializeArray方法将表单中数据转换成json格式的数组:[{name:"a",value"1"},{name:"b",value"2"}],其中this代表当前表单对象
		           var str=this.serialize();  
		           $(array).each(function(){  //遍历json数组
		               if(serializeObj[this.name]){  
		                   if($.isArray(serializeObj[this.name])){  
		                       serializeObj[this.name].push(this.value);  
		                   }else{  
		                       serializeObj[this.name]=[serializeObj[this.name],this.value];  
		                   }  
		               }else{  
		                   serializeObj[this.name]=this.value;   
		               }  
		           });  
		           return serializeObj;  //最终转换完成之后的json对象 [{"a":"1"},{"b":"2"}]
		       }; 
			//---------------------自定义的将表单中数据序列化为json对象的方法---------------------------
			
			$("#searchBtn").click(function(){
				//获取表单中的数据
				var json = $("#searchForm").serializeJson();
				//重新让datagrid发送一次ajax请求
				$("#grid").datagrid("load",json);
				//关闭查询窗口
				$("#searchWindow").window("close");
			});
		});
	</script>

4、问题:如何让搜索窗口打开后其他按钮不能点击

(1)、之前的效果


(2)、添加窗口的属性


(3)、之后的效果


5、改造后台CourierAction代码


	/**
	 * 分页查询方法
	 * @throws Exception 
	 */
	@Action(value="courierAction_pageQuery")
	public String pageQuery() throws Exception{
		
		//获取查询条件
		final String company = model.getCompany();
		final String courierNum = model.getCourierNum();
		final String type = model.getType();
		final Standard standard = model.getStandard();
		//动态根据页面提交的参数封装查询条件
		Specification<Courier> spe = new Specification<Courier>(){
			
			public Predicate toPredicate(Root<Courier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				//创建集合用于封装查询条件
				List<Predicate> list = new ArrayList<Predicate>();
				if(StringUtils.isNotBlank(company)){
					//需要添加一个过滤条件,根据公司模糊查询
					Predicate p1 = cb.like(root.get("company").as(String.class), company); //where company like ?
					list.add(p1);
				}
				if(StringUtils.isNotBlank(courierNum)){
					//需要添加一个过滤条件,根据编号等值查询
					Predicate p2 = cb.equal(root.get("courierNum").as(String.class), courierNum); //where courierNum = ?
					list.add(p2);
				}
				if(StringUtils.isNotBlank(type)){
					//需要添加一个过滤条件,根据类型等值查询
					Predicate p3 = cb.equal(root.get("type").as(String.class), type); //where type = ?
					list.add(p3);
				}
				if(standard != null && StringUtils.isNotBlank(standard.getName())){
					//需要添加一个过滤条件,根据收派标准等值查询
					Join<Object, Object> join = root.join("standard");
					Predicate p4 = cb.equal(join.get("name").as(String.class), standard.getName()); //where standard.name = ?
					list.add(p4);
				}
				if(list.size() == 0){
					return null;
				}else{
					Predicate[] ps = new Predicate[list.size()];
					return cb.and(list.toArray(ps));//如果各个条件之间是and关系,就用and方法,如果是or关系,就用or方法
				}
			}
		};
		//创建一个pageable对象,封装分页参数
		Pageable pageable = new PageRequest(page - 1, rows);
		//调用方法查询分页对象
		Page<Courier> page = serivce.pageQuery(spe,pageable);
		//获取总条数
		long total = page.getTotalElements();
		//获取数据集合
		List<Courier> rows = page.getContent();
		//定义map,封装数据
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("total", total);
		map.put("rows", rows);
		//转换json,使用jsonConfig排除对象中不需要转换的属性
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[]{"fixedAreas","takeTime"});//fixedAreas是Courier类中的一个属性
		String data = JSONObject.fromObject(map,jsonConfig).toString();
		//使用输出流将数据写回到浏览器
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/json;charset=UTF-8");
		response.getWriter().print(data);
		return NONE;
	}

6、修改CourierService层代码

	/**
	 * 带有查询条件的分页查询方法
	 */
	public Page<Courier> pageQuery(Specification<Courier> spe, Pageable pageable) {
		return dao.findAll(spe,pageable);
	}

7、修改CourierDao层代码


package com.itheima.bos.dao.base;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import com.itheima.bos.domain.base.Courier;

/**
 * 继承JpaSpecificationExecutor<Courier>是为了可以使用该类提供的动态封装分页查询条件的方法
 * @author Administrator
 *
 */
public interface CourierDao extends JpaRepository<Courier, Integer>,JpaSpecificationExecutor<Courier> {

	/**
	 * 批量删除收派员 -- 逻辑删除
	 * @param courierId
	 */
	@Query("update Courier set deltag = '1' where id = ?")
	@Modifying
	public void deleteCourier(int courierId);

}

二、区域数据批量导入功能

1、一键上传原理演示


2、JQuery OCUpload 一键上传插件的使用

(1)、引入一键上传的js文件


(2)、在html页面编写代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
	<!-- 引入easyui资源文件 -->
	<link rel="stylesheet" type="text/css" href="../js/easyui/themes/default/easyui.css">
	<link rel="stylesheet" type="text/css" href="../js/easyui/themes/icon.css">
	<script type="text/javascript" src="../js/jquery-1.8.3.js"></script>
	<script type="text/javascript" src="../js/easyui/jquery.easyui.min.js"></script>
	<script type="text/javascript" src="../js/easyui/locale/easyui-lang-zh_CN.js"></script>
	<script type="text/javascript" src="../js/easyui/locale/easyui-lang-zh_CN.js"></script>
	<script type="text/javascript" src="../js/ocupload/jquery.ocupload-1.1.2.js"></script>
	
	<!-- 一键上传文件的方法 -->
	<script type="text/javascript">
		$(function(){
			$("#mybutton").upload({
				name:'myFileName',
				action:'xx.action'
			});
		});
	</script>
</head>
<body>
	<input id="mybutton" type="button" value="上传文件">
</body>
</html>

(3)、页面提交之后的效果


3、在area.html页面添加一键上传功能


4、POI解析Excel文件使用说明

(1)、需要的jar包


(2)、测试类

package bos_management_web;

import java.io.File;
import java.io.FileInputStream;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.junit.Test;

/**
 * 测试POI读取Excel
 * @author Administrator
 *
 */
public class POITest {

	@Test
	public void testPOI() throws Exception{
		//指定要读取的文件位置
		String path = "C:\\Users\\Administrator\\Desktop\\区域导入测试数据.xls";
		//通过输入流,加载指定的Excel文件
		HSSFWorkbook book = new HSSFWorkbook(new FileInputStream(new File(path)));
		//指定读取哪个标签页 -- sheet
		HSSFSheet sheet = book.getSheetAt(0);
		//遍历标签中的所有行
		for (Row row : sheet) {
			//获取行号 -- 行号是从0开始的
			int rowNum = row.getRowNum();
			if(rowNum == 0){
				//是第一行数据,忽略
				continue;
			}
			for (Cell cell : row) {
				//遍历行中所有的单元格
				String value = cell.getStringCellValue();
				System.out.print(value+" 	");
			}
			System.out.println();
		}
	}
}

(3)、效果


5、服务器端接收上传的Excel文件

(1)、AreaAction代码编写

package com.itheima.bos.web.action.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.itheima.bos.domain.base.Area;
import com.itheima.bos.service.base.AreaService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@Controller
@Namespace("/")
@Scope("prototype")
@ParentPackage("struts-default")
public class AreaAction extends ActionSupport implements ModelDriven<Area>{

	private Area model = new Area();
	
	public Area getModel() {
		return model;
	}
	
	//定义变量,接收上传的文件
	private File areaFile;

	public void setAreaFile(File areaFile) {
		this.areaFile = areaFile;
	}
	
	//实例化service层对象
	@Autowired
	private AreaService areaService;
	
	/**
	 * 接收上传的xlsx表格内容
	 * @throws Exception 
	 * @throws FileNotFoundException 
	 */
	@Action(value="areaAction_importXls")
	public String upload() throws Exception{
		//使用POI读取上传的Excle表格内容
		HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(areaFile));
		//获取第一个sheet
		HSSFSheet sheet = workbook.getSheet("Sheet1");
		//定义集合接收Area对象
		List<Area> list = new ArrayList<Area>();
		//遍历sheet中的每一行数据
		for (Row row : sheet) {
			if(row.getRowNum() == 0){
				continue;
			}
			String id = row.getCell(0).getStringCellValue();
			String province = row.getCell(1).getStringCellValue();
			String city = row.getCell(2).getStringCellValue();
			String district = row.getCell(3).getStringCellValue();
			String postcode = row.getCell(4).getStringCellValue();
			Area area = new Area(id,province,city,district,postcode);
			//将对象添加到集合中
			list.add(area);
		}
		//调用方法,进行保存
		areaService.save(list);
		return NONE;
	}

}

(2)、AreaService代码编写

package com.itheima.bos.service.base.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.itheima.bos.dao.base.AreaDao;
import com.itheima.bos.domain.base.Area;
import com.itheima.bos.service.base.AreaService;
@Service
@Transactional
public class AreaServicImpl implements AreaService {

	@Autowired
	private AreaDao areaDao;
	/**
	 * 添加区域
	 */
	public void save(List<Area> list) {
		areaDao.save(list);
	}

}

(3)、AreaDao代码编写

package com.itheima.bos.dao.base;

import org.springframework.data.jpa.repository.JpaRepository;

import com.itheima.bos.domain.base.Area;

public interface AreaDao extends JpaRepository<Area, String> {

}
6、使用pinyin4J生成简码和城市编码

(1)、需要使用的jar包


(2)、导入pinyin4j的工具类

package com.itheima.bos.utils;

import java.util.Arrays;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

public class PinYin4jUtils {
	/**
	 * 将字符串转换成拼音数组
	 * 
	 * @param src
	 * @return
	 */
	public static String[] stringToPinyin(String src) {
		return stringToPinyin(src, false, null);
	}

	/**
	 * 将字符串转换成拼音数组
	 * 
	 * @param src
	 * @return
	 */
	public static String[] stringToPinyin(String src, String separator) {

		return stringToPinyin(src, true, separator);
	}

	/**
	 * 将字符串转换成拼音数组
	 * 
	 * @param src
	 * @param isPolyphone
	 *            是否查出多音字的所有拼音
	 * @param separator
	 *            多音字拼音之间的分隔符
	 * @return
	 */
	public static String[] stringToPinyin(String src, boolean isPolyphone,
			String separator) {
		// 判断字符串是否为空
		if ("".equals(src) || null == src) {
			return null;
		}
		char[] srcChar = src.toCharArray();
		int srcCount = srcChar.length;
		String[] srcStr = new String[srcCount];

		for (int i = 0; i < srcCount; i++) {
			srcStr[i] = charToPinyin(srcChar[i], isPolyphone, separator);
		}
		return srcStr;
	}

	/**
	 * 将单个字符转换成拼音
	 * 
	 * @param src
	 * @return
	 */
	public static String charToPinyin(char src, boolean isPolyphone,
			String separator) {
		// 创建汉语拼音处理类
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		// 输出设置,大小写,音标方式
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

		StringBuffer tempPinying = new StringBuffer();

		// 如果是中文
		if (src > 128) {
			try {
				// 转换得出结果
				String[] strs = PinyinHelper.toHanyuPinyinStringArray(src,
						defaultFormat);

				// 是否查出多音字,默认是查出多音字的第一个字符
				if (isPolyphone && null != separator) {
					for (int i = 0; i < strs.length; i++) {
						tempPinying.append(strs[i]);
						if (strs.length != (i + 1)) {
							// 多音字之间用特殊符号间隔起来
							tempPinying.append(separator);
						}
					}
				} else {
					tempPinying.append(strs[0]);
				}

			} catch (BadHanyuPinyinOutputFormatCombination e) {
				e.printStackTrace();
			}
		} else {
			tempPinying.append(src);
		}

		return tempPinying.toString();

	}

	public static String hanziToPinyin(String hanzi) {
		return hanziToPinyin(hanzi, " ");
	}

	/**
	 * 将汉字转换成拼音
	 * 
	 * @param hanzi
	 * @param separator
	 * @return
	 */
	public static String hanziToPinyin(String hanzi, String separator) {

		// 创建汉语拼音处理类
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		// 输出设置,大小写,音标方式
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

		String pinyingStr = "";
		try {
			pinyingStr = PinyinHelper.toHanyuPinyinString(hanzi, defaultFormat,
					separator);
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return pinyingStr;
	}

	/**
	 * 将字符串数组转换成字符串
	 * 
	 * @param str
	 * @param separator
	 *            各个字符串之间的分隔符
	 * @return
	 */
	public static String stringArrayToString(String[] str, String separator) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < str.length; i++) {
			sb.append(str[i]);
			if (str.length != (i + 1)) {
				sb.append(separator);
			}
		}
		return sb.toString();
	}

	/**
	 * 简单的将各个字符数组之间连接起来
	 * 
	 * @param str
	 * @return
	 */
	public static String stringArrayToString(String[] str) {
		return stringArrayToString(str, "");
	}

	/**
	 * 将字符数组转换成字符串
	 * 
	 * @param str
	 * @param separator
	 *            各个字符串之间的分隔符
	 * @return
	 */
	public static String charArrayToString(char[] ch, String separator) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < ch.length; i++) {
			sb.append(ch[i]);
			if (ch.length != (i + 1)) {
				sb.append(separator);
			}
		}
		return sb.toString();
	}

	/**
	 * 将字符数组转换成字符串
	 * 
	 * @param str
	 * @return
	 */
	public static String charArrayToString(char[] ch) {
		return charArrayToString(ch, " ");
	}

	/**
	 * 取汉字的首字母
	 * 
	 * @param src
	 * @param isCapital
	 *            是否是大写
	 * @return
	 */
	public static char[] getHeadByChar(char src, boolean isCapital) {
		// 如果不是汉字直接返回
		if (src <= 128) {
			return new char[] { src };
		}
		// 获取所有的拼音
		String[] pinyingStr = PinyinHelper.toHanyuPinyinStringArray(src);

		// 创建返回对象
		int polyphoneSize = pinyingStr.length;
		char[] headChars = new char[polyphoneSize];
		int i = 0;
		// 截取首字符
		for (String s : pinyingStr) {
			char headChar = s.charAt(0);
			// 首字母是否大写,默认是小写
			if (isCapital) {
				headChars[i] = Character.toUpperCase(headChar);
			} else {
				headChars[i] = headChar;
			}
			i++;
		}

		return headChars;
	}

	/**
	 * 取汉字的首字母(默认是大写)
	 * 
	 * @param src
	 * @return
	 */
	public static char[] getHeadByChar(char src) {
		return getHeadByChar(src, true);
	}

	/**
	 * 查找字符串首字母
	 * 
	 * @param src
	 * @return
	 */
	public static String[] getHeadByString(String src) {
		return getHeadByString(src, true);
	}

	/**
	 * 查找字符串首字母
	 * 
	 * @param src
	 * @param isCapital
	 *            是否大写
	 * @return
	 */
	public static String[] getHeadByString(String src, boolean isCapital) {
		return getHeadByString(src, isCapital, null);
	}

	/**
	 * 查找字符串首字母
	 * 
	 * @param src
	 * @param isCapital
	 *            是否大写
	 * @param separator
	 *            分隔符
	 * @return
	 */
	public static String[] getHeadByString(String src, boolean isCapital,
			String separator) {
		char[] chars = src.toCharArray();
		String[] headString = new String[chars.length];
		int i = 0;
		for (char ch : chars) {

			char[] chs = getHeadByChar(ch, isCapital);
			StringBuffer sb = new StringBuffer();
			if (null != separator) {
				int j = 1;

				for (char ch1 : chs) {
					sb.append(ch1);
					if (j != chs.length) {
						sb.append(separator);
					}
					j++;
				}
			} else {
				sb.append(chs[0]);
			}
			headString[i] = sb.toString();
			i++;
		}
		return headString;
	}
	
	public static void main(String[] args) {
		// pin4j 简码 和 城市编码 
		String s1 = "中华人民共和国"; 
		String[] headArray = getHeadByString(s1); // 获得每个汉字拼音首字母
		System.out.println(Arrays.toString(headArray));
		
		String s2 ="长城" ; 
		System.out.println(Arrays.toString(stringToPinyin(s2,true,",")));
		
		String s3 ="长";
		System.out.println(Arrays.toString(stringToPinyin(s3,true,",")));
	}
}

(3)、编写测试类

package bos_management_web;

import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import com.itheima.bos.utils.PinYin4jUtils;

public class Pinyin4JTest {

	@Test
	public void testPinYin4J(){
		//北京省北京市昌平区
		String province = "北京省";
		String city = "北京市";
		String district = "昌平区";
		
		//简码 --> BJBJCP
		province = province.substring(0, province.length() - 1);
		city = city.substring(0, city.length() - 1);
		district = district.substring(0, district.length() - 1);
		
		//调用pinyin4J进行转码
		String[] headByString = PinYin4jUtils.getHeadByString(province + city + district);
		String shortcode = StringUtils.join(headByString);
		System.out.println(shortcode);
		//城市编码 --> beijing
		String citycode = PinYin4jUtils.hanziToPinyin(city,"");
	}
}

(4)、修改action代码


三、区域分页查询

1、修改area.html中获取所有数据的url


2、编写AreaAction中的分页查询方法

	//定义变量,接收分页参数
	private int page;
	private int rows;
	
	public void setPage(int page) {
		this.page = page;
	}


	public void setRows(int rows) {
		this.rows = rows;
	}


	/**
	 * 分页查询的方法
	 * @throws Exception 
	 */
	@Action(value="areaAction_pageQuery")
	public String pagequery() throws Exception{
		//创建pageable对象,封装分页参数
		Pageable pageable = new PageRequest(page - 1, rows);
		Page<Area> page = areaService.findAll(pageable);
		//获取总条数
		long total = page.getTotalElements();
		//获取所有集合
		List<Area> rows = page.getContent();
		//封装数据到map集合中
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("total", total);
		map.put("rows", rows);
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[]{"subareas"});
		String data = JSONObject.fromObject(map, jsonConfig).toString();
		//使用输出流将数据写入浏览器
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/json;charset=UTF-8");
		response.getWriter().print(data);
		return NONE;
	}

3、编写AreaService中的分页查询方法

	/**
	 * 分页查询所有数据
	 */
	public Page<Area> findAll(Pageable pageable) {

		return areaDao.findAll(pageable);
	}

四、代码重构

1、创建公共的Action类


2、在公共的Aciton类中抽取公共的方法

package com.itheima.bos.web.action.base.common;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.springframework.data.domain.Page;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

/**
 * 定义公共Action
 * 
 * @author Administrator
 *
 */
public class CommonAction<T> extends ActionSupport implements ModelDriven<T> {

	private T model;

	public T getModel() {
		return model;
	}

	/**
	 * 抽取创建model模型驱动对象的方法 在运行期间动态获得泛型的具体类型,并通过反射创建model对象
	 */
	public CommonAction() {
		// 说去父类(CommonAction)对应的类型
		ParameterizedType superclass = (ParameterizedType) this.getClass().getGenericSuperclass();
		// 获得父类上声明的泛型类型数组
		Type[] types = superclass.getActualTypeArguments();
		// 获取当前子类的实体类的类型
		Class<T> entityClass = (Class<T>) types[0];
		// 通过反射创建model对象
		try {
			model = entityClass.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 抽取属性驱动封装分页参数的方法
	 */
	protected int page; //修饰符为protected,子类可以使用
	protected int rows;

	public void setPage(int page) {
		this.page = page;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}
	
	/**
	 * 抽取分页中转json并相应到客户端浏览器的代码
	 */
	public void page2json(Page page, String[] excludes){
		//获取总记录数
		long total = page.getTotalElements();
		List<T> rows = page.getContent();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("total", total);
		map.put("rows", rows);
		//对象转JSON,并排除不需要转的属性
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(excludes);
		String data = JSONObject.fromObject(map, jsonConfig).toString();
		//使用输出流将数据写回客户端浏览器
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/json;charset=UTF-8");
		try {
			response.getWriter().print(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * List转json
	 */
	public void list2json(List list, String[] excludes){
		//对象转JSON,并排除不需要转的属性
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(excludes);
		String data = JSONArray.fromObject(list, jsonConfig).toString();
		//使用输出流将数据写回客户端浏览器
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/json;charset=UTF-8");
		try {
			response.getWriter().print(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

3、改造StandarAction、CourierAction、AreaAction中的代码

(1)、StandarAction

package com.itheima.bos.web.action.base;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;

import com.itheima.bos.domain.base.Standard;
import com.itheima.bos.service.base.StandardService;
import com.itheima.bos.web.action.base.common.CommonAction;

import net.sf.json.JSONArray;

/**
 * 收派标准的动作类
 * 
 * @author Administrator
 *
 */
@Namespace("/")
@ParentPackage("struts-default")
@Controller
@Scope("prototype")
public class StandardAction extends CommonAction<Standard> {

	private Standard model = this.getModel();

	@Override
	public Standard getModel() {
		return model;
	}

	@Autowired
	private StandardService standardService;

	/*
	 * 保存收派标准
	 */
	@Action(value = "standardAction_save", results = {
			@Result(name = "success", type = "redirect", location = "/pages/base/standard.html") })
	public String save() {
		standardService.save(model);
		return "success";
	}

	/**
	 * 收派标准分页查询
	 */
	@Action(value = "standardAction_pageQuery")
	public String pageQuery() throws Exception {
		// 创建一个pageable对象,封装分页参数,pageable对象是spring data JPA提供的一个对象,用来做分页的
		Pageable pageable = new PageRequest(page - 1, rows);// 注意:pageable中当前页是从0开始的,所以要 - 1
		Page<Standard> page = standardService.pageQuery(pageable);
		// 创建不需要转json的属性集合
		String[] excludes = new String[] { "" };
		// 调用父类的方法,进行转json并且输出到客户端浏览器
		super.page2json(page, excludes);
		return NONE;
	}

	/**
	 * 获取所有收派标准
	 * 
	 * @throws Exception
	 */
	@Action(value = "standardAction_findAll")
	public String findAll() throws Exception {
		List<Standard> sList = standardService.findAll();
		String data = JSONArray.fromObject(sList).toString();
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/json;charset=UTF-8");
		response.getWriter().print(data);
		return NONE;
	}

}

(2)、CourierAction

package com.itheima.bos.web.action.base;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;

import com.itheima.bos.domain.base.Courier;
import com.itheima.bos.domain.base.Standard;
import com.itheima.bos.service.base.CourierService;
import com.itheima.bos.web.action.base.common.CommonAction;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

@Controller
@Namespace("/")
@ParentPackage("struts-default")
@Scope("prototype")
public class CourierAction extends CommonAction<Courier> {

	private Courier model = this.getModel();

	@Autowired
	private CourierService serivce;

	@Action(value = "courierAction_save", results = {
			@Result(name = "success", type="redirect", location = "/pages/base/courier.html") })
	public String save() {
		serivce.save(model);
		return SUCCESS;
	}

	/**
	 * 分页查询方法
	 * @throws Exception 
	 */
	@Action(value="courierAction_pageQuery")
	public String pageQuery() throws Exception{
		
		//获取查询条件
		final String company = model.getCompany();
		final String courierNum = model.getCourierNum();
		final String type = model.getType();
		final Standard standard = model.getStandard();
		//动态根据页面提交的参数封装查询条件
		Specification<Courier> spe = new Specification<Courier>(){
			
			public Predicate toPredicate(Root<Courier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				//创建集合用于封装查询条件
				List<Predicate> list = new ArrayList<Predicate>();
				if(StringUtils.isNotBlank(company)){
					//需要添加一个过滤条件,根据公司模糊查询
					Predicate p1 = cb.like(root.get("company").as(String.class), company); //where company like ?
					list.add(p1);
				}
				if(StringUtils.isNotBlank(courierNum)){
					//需要添加一个过滤条件,根据编号等值查询
					Predicate p2 = cb.equal(root.get("courierNum").as(String.class), courierNum); //where courierNum = ?
					list.add(p2);
				}
				if(StringUtils.isNotBlank(type)){
					//需要添加一个过滤条件,根据类型等值查询
					Predicate p3 = cb.equal(root.get("type").as(String.class), type); //where type = ?
					list.add(p3);
				}
				if(standard != null && StringUtils.isNotBlank(standard.getName())){
					//需要添加一个过滤条件,根据收派标准等值查询
					Join<Object, Object> join = root.join("standard");
					Predicate p4 = cb.equal(join.get("name").as(String.class), standard.getName()); //where standard.name = ?
					list.add(p4);
				}
				if(list.size() == 0){
					return null;
				}else{
					Predicate[] ps = new Predicate[list.size()];
					return cb.and(list.toArray(ps));//如果各个条件之间是and关系,就用and方法,如果是or关系,就用or方法
				}
			}
			
		};
		//创建一个pageable对象,封装分页参数
		Pageable pageable = new PageRequest(page - 1, rows);
		//调用方法查询分页对象
		Page<Courier> page = serivce.pageQuery(spe,pageable);
		//创建不需要转json的属性集合
		String[] excludes = new String[]{"fixedAreas","takeTime"};
		//调用父类的方法,进行转json并且输出到客户端浏览器
		super.page2json(page, excludes);
		return NONE;
	}
	
	//属性驱动封装后台传递的多个id拼接的字符串
	private String ids;
	
	public void setIds(String ids) {
		this.ids = ids;
	}

	/**
	 * 批量删除的方法
	 */
	@Action(value="courierAction_deleteBatch",results={
			@Result(name="success",type="redirect",location="/pages/base/courier.html")
	})
	public String deleteBatch(){
		serivce.deleteBatch(ids);
		return SUCCESS;
	}

}

(3)、AreaAction

package com.itheima.bos.web.action.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;

import com.itheima.bos.domain.base.Area;
import com.itheima.bos.service.base.AreaService;
import com.itheima.bos.utils.PinYin4jUtils;
import com.itheima.bos.web.action.base.common.CommonAction;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

@Controller
@Namespace("/")
@Scope("prototype")
@ParentPackage("struts-default")
public class AreaAction extends CommonAction<Area> {

	private Area model = this.getModel();

	// 定义变量,接收上传的文件
	private File areaFile;

	public void setAreaFile(File areaFile) {
		this.areaFile = areaFile;
	}

	// 实例化service层对象
	@Autowired
	private AreaService areaService;

	/**
	 * 接收上传的xlsx表格内容
	 * 
	 * @throws Exception
	 * @throws FileNotFoundException
	 */
	@Action(value = "areaAction_importXls")
	public String upload() throws Exception {
		// 使用POI读取上传的Excle表格内容
		HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(areaFile));
		// 获取第一个sheet
		HSSFSheet sheet = workbook.getSheet("Sheet1");
		// 定义集合接收Area对象
		List<Area> list = new ArrayList<Area>();
		// 遍历sheet中的每一行数据
		for (Row row : sheet) {
			if (row.getRowNum() == 0) {
				continue;
			}
			String id = row.getCell(0).getStringCellValue();
			String province = row.getCell(1).getStringCellValue();
			String city = row.getCell(2).getStringCellValue();
			String district = row.getCell(3).getStringCellValue();
			String postcode = row.getCell(4).getStringCellValue();
			Area area = new Area(id, province, city, district, postcode);
			// 使用pinyin4j生成城市编码
			// 北京省北京市昌平区
			// 简码
			province = province.substring(0, province.length() - 1);
			city = city.substring(0, city.length() - 1);
			district = district.substring(0, district.length() - 1);

			// 调用pinyin4J进行转码
			String[] headByString = PinYin4jUtils.getHeadByString(province + city + district);
			String shortcode = StringUtils.join(headByString);
			// 城市编码 --> beijing
			String citycode = PinYin4jUtils.hanziToPinyin(city, "");

			area.setShortcode(shortcode);
			area.setCitycode(citycode);
			// 将对象添加到集合中
			list.add(area);
		}
		// 调用方法,进行保存
		areaService.save(list);
		return NONE;
	}

	/**
	 * 分页查询的方法
	 * 
	 * @throws Exception
	 */
	@Action(value = "areaAction_pageQuery")
	public String pagequery() throws Exception {
		// 创建pageable对象,封装分页参数
		Pageable pageable = new PageRequest(page - 1, rows);
		Page<Area> page = areaService.findAll(pageable);

		// 创建不需要转json的属性结合
		String[] excludes = new String[] { "subareas" };
		// 调用父类的方法,进行转json并且输出到客户端浏览器
		super.page2json(page, excludes);

		return NONE;
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值