Java

poi – 生成excel时使表头比较醒目、好看

CellStyle style = sheet.getWorkbook().createCellStyle(); //置成黄色 style.setFillForegroundColor(IndexedColors.YELLOW.getIndex()); style.setFillPattern(CellStyle.SOLID_FOREGROUND); //表头的边界线清晰可见 style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); Row header = sheet.createRow(0); int columnIndex = 0; for (…) { Cell cell = createCell(header, columnIndex); cell.setCellValue(headerText); cell.setCellStyle(style); //表头cell的宽度适应文字 sheet.autoSizeColumn(columnIndex); columnIndex++; }

分布式系统中的三种接口粒度

分布式系统中有三种接口粒度: 1. 内部用的domain service接口。这个接口最精致。   a. 出入参数跟数据库表有比较强的对应,基本上一个对象对应一张表。   b. 入参数据都假定已清洗,不必再校验。   c. 业务逻辑主要是CRUD+高度可重用的核心业务逻辑。   d. 返回数据一般是数据对象或者它们的类集。错误信息一般直接通过exception返回。 2. 供移动或web前端调用、或者供外部系统调用、面向use case的app service接口。这个接口最重。   a. 出入参数一般对应数据库中的多张表中的数据,还会有一些use case特有的字段,比如一个“帖子”对象中会给出“帖子作者的头像”、“当前用户能否删除本贴”、“帖子被评论次数”等。 这一层的数据对象是DTO(value object), 一般要从多个domain层对象的字段中组合而来。   b. 入参数据由用户直接输入或非可信系统输入,所以需要校验。   c.  业务逻辑一般需要通过组合多个domain service实现,比如 N个crud +  1个权限校验 + 1个展示层数据填充等,很难重用。   d. 返回数据一般是Result对象: 数据对象 + 错误码 + 错误信息, 不再抛exception. 3. 给内部可信系统调用的rpc service接口。这个接口的轻、重介于上面两种之间。   a. 出入参数包含的字段往往比domain层参数的稍多一点,比app层参数的少一些或少很多。   …

分布式系统中的三种接口粒度 Read More »

poi – 安全地把cell当作string读出来

如果cell并非string类型,调用cell.getStringCellValue()会出错。 下面这样可以保证安全: private String readString(Cell cell) { if (cell == null) { return null; } int cellType = cell.getCellType(); if (cellType == Cell.CELL_TYPE_BLANK) { return null; } if (cellType == Cell.CELL_TYPE_BOOLEAN) { return String.valueOf(cell.getBooleanCellValue()); } if (cellType == Cell.CELL_TYPE_ERROR) { return null; } if (cellType == Cell.CELL_TYPE_FORMULA) { return cell.getCellFormula(); } if (cellType == Cell.CELL_TYPE_NUMERIC) …

poi – 安全地把cell当作string读出来 Read More »

使用时注意proxy-target-class选项

如果使用的是默认的<aop:aspectj-autoproxy/>,当target有interface时,生成proxy会实现这个interface,但这个proxy并不是target的子类。 有时候,你的target有interface, 但仍然有自己的public方法需要暴露,这时你应该保证你的aop proxy会继承target. 办法就是: 引用 <aop:aspectj-autoproxy proxy-target-class="true"/>

代码片断:获取一个类集中所有元素的某个属性

怎么从 List<Person> personList中取出 List<Long> idList ?  没有闭包语法的情况下,你只能写一个for循环,一个一个往里塞。。。 老写这种东西,会不胜期烦。 可以写个微型的框架,让你写更少更简洁的代码完成这种事情。 你会这样用: List<Long> idList = MyCollectionUtils.extractProperty( personList, GetPersonIdPropCommand()); public static final class GetPersonIdPropCommand implements GetPropertyCommand<Person, Long> { …… } 框架在这里: /** * 从一个类集中抽取中每个元素的某个属性. 举例说明:{person1, person2} => {person1Id, person2Id} * * * @param objects * @param getPropCommand * @return */ public static <O, P> ArrayList<P> extractProperty(Collection<O> objects, GetPropertyCommand<O, …

代码片断:获取一个类集中所有元素的某个属性 Read More »

代码片断:安全的subList()方法

/** * 从类集中找到前几个元素,组成新的类集再返回。 <br/> * 1. 如果想要的元素个数超过了类集的大小,则返回该类集中的所有元素组成的类集 <br/> * 2. 原类集对象不会被修改<br/> * 3. 返回ArrayList,它可能为empty,但不会是null<br/> * * @param list * @param elementCount * 想要的元素个数; 如果个数不是正数,则返回空list * @return */ public static <T> ArrayList<T> selectTopElements(List<T> list, int elementCount) { ArrayList<T> resultList = new ArrayList<T>(); if (list == null) { return resultList; } if (elementCount <= 0) { return resultList; …

代码片断:安全的subList()方法 Read More »

ibatis里存取enum类型

enum类型不是标准的jdbcType, 所以你要使用 type handler配置一下映射。数据库里使用varchar类型,存储enum字段的name . /** * ibatis内置了一个EnumTypeHandler, * 但它没有无参构造函数,直接使用它会导致java.lang.InstantiationException, 所以你要另建一个类,提供一个无参构造函数,并利用装饰器模式集成EnumTypeHandler的功能。 * ibatis内置的EnumTypeHandler还有一个缺点: 对于数据库里存储的脏数据即不在指定enum * name范围之内的数据,EnumTypeHandler在运行时会直接报异常; 但在一般的应用场景下,我们希望把这些脏数据解析成null就可以了。 * 所以,我们的新类里应该在这方面提供健壮性。 * * 用法:对每个具体的枚举,请继承一下本类 * * @author kent * */ @SuppressWarnings(“rawtypes”) public abstract class MyEnumTypeHandler extends BaseTypeHandler implements TypeHandler { private EnumTypeHandler delegate; public MyEnumTypeHandler() { Class type = this.getEnumType(); delegate = new EnumTypeHandler(type); } public abstract …

ibatis里存取enum类型 Read More »

关于unicode中的bmp

最早版本的unicode所允许的值是 U+0000 to U+FFFF 后来unicode扩充了,取值范围变成了U+0000 to U+10FFFF . 原先的 U+0000 to U+FFFF这个集合就称作BMP (Basic Multilingual Plane) 这个集合也是mysql utf8_general字符集所能支持的集合(三个字节); 所以,java在插入文字之前应该过滤掉non-bmp字符。 public static String removeNonBmpUnicode(String str) { if (str == null) { return null; } str = str.replaceAll("[^\\u0000-\\uFFFF]", ""); return str; } BMP之外的字符集合称为"supplementary characters". 由于Java里每个char都是用16位来表示的,一个supplementary character在java里就要用两个特殊的bmp字符来表示。这类特殊的bmp字符分别称作high-surrogates(\uD800-\uDBFF) 和 low-surrogates(\uDC00-\uDFFF). 要注意的是,把surrogates用在java6的正则中时,得到的结果会让人很意外: //\ud83d\udd12是一个unicode单字(”锁“的形状) "\ud83d\udd12".matches("\ud83d\udd12") == true //这个好理解 "\ud83d\udd12".matches("\\ud83d\\udd12") == false //为什么?java.util.regex.Pattern的javadoc不是说 …

关于unicode中的bmp Read More »