上篇博客介绍了通过反射读取Jar包的类名和属性名,但是问题是读不出类名和属性名的中文注释和属性类型。所以上篇博客埋下了一个伏笔,就是通过自定义注解的方式读取Jar包的类名、属性名、中文注释和属性类型。这篇博客我们就来好好讲讲是如何实现的。
首先先说一下,由于我们的Jar包没有放到项目下,所以就想着怎么能把Jar包添加进来,所以先做了一个类似于上传文件的功能,将Jar上传进来,然后再读取Jar包里面的类名、属性名等一系列属性,再添加到数据库中。总体的思路确定了,下面就开始实施。
首先是上传Jar包。这个我以前写过springMVC的文件上传的博客,具体可以参考我之前写的博客。
/**
* Jar包上传
* @param request
* @param response
* @return
* @throws IllegalStateException
* @throws IOException
*/
@RequestMapping("/upload2")
public String upload2(HttpServletRequest request,HttpServletResponse response) throws IllegalStateException, IOException{
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
//判断request里面是否是Multipart类型的数据
if(multipartResolver.isMultipart(request)){
//把request强制转换成MultipartHttpServletRequest类型的
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
//用迭代器去判断里面有多少文件,遍历文件的一个方法
Iterator<String> iter = multiRequest.getFileNames();
while (iter.hasNext()) {
//迭代器的作用就是一个一个拿文件,把文件拿到
MultipartFile file = multiRequest.getFile((String)iter.next());
if(file != null){
//拿到文件之后输出文件
//首先定义文件名称
String fileName = file.getOriginalFilename();
//定义输出路径
String path = "G:/" + fileName;
String fromFilePath = "G:\\" + fileName;
//初始化文件
File localFile = new File(path);
//用stringMVC给咱们提供的方法给它写到本地去
file.transferTo(localFile);
try {
getJarName(fromFilePath, request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return "/UploadJarBag";
下面就是为自定义注解做准备了,自定义一个注解解析器
package com.tgb.itoo.uisystem.entity;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 定义一个注解解析器
* @author 高迎
* @date 2015年3月11日10:10:49
*
*/
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface FieldMeta {
/**
* 是否为序列号
* @return
*/
boolean id() default false;
/**
* 字段名称
* @return
*/
String name() default "";
/**
* 字段长度,默认值为255
* @return
*/
int length() default 255;
/**
* 是否可编辑
* @return
*/
boolean editable() default true;
/**
* 是否在列表中显示
* @return
*/
boolean summary() default true;
/**
* 字段描述
* @return
*/
String description() default "";
} 定义一个获得注解的帮助类package com.tgb.itoo.uisystem.controller;
import java.lang.reflect.Field;
import com.tgb.itoo.uisystem.entity.FieldMeta;
/**
* 获得到注解的帮助类
* @author 高迎
* @date 2015年3月11日10:12:15
*
*/
public class SortableField {
public SortableField(){}
public SortableField(FieldMeta meta, Field field) {
super();
this.meta = meta;
this.field = field;
this.name=field.getName();
this.type=field.getType();
}
public SortableField(FieldMeta meta, Field field, int length) {
super();
this.meta = meta;
this.field = field;
this.name=field.getName();
this.type=field.getType();
this.length=length;
}
public SortableField(FieldMeta meta, String name, int length, Class<?> type) {
super();
this.meta = meta;
this.name = name;
this.length = length;
this.type = type;
}
private FieldMeta meta;
private Field field;
private String name;
private int length;
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
private Class<?> type;
public FieldMeta getMeta() {
return meta;
}
public void setMeta(FieldMeta meta) {
this.meta = meta;
}
public Field getField() {
return field;
}
public void setField(Field field) {
this.field = field;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
}
通过自定义注解读取Jar包的属性
/**
* 读取jar包的类名和属性名
* @param jarFile
* @throws Exception
*/
public void getJarName(String jarFile, HttpServletRequest request, HttpServletResponse response) throws Exception {
//定义一个注解帮助类类型的list
List<SortableField> list = new ArrayList<SortableField>();
try{
//通过将给定路径名字符串转换为抽象路径名来创建一个新File实例
File f = new File(jarFile);
URL realURL = f.toURI().toURL();
URLClassLoader myClassLoader = new URLClassLoader(new URL[]{realURL},Thread.currentThread().getContextClassLoader());
//通过jarFile和JarEntry得到所有的类
JarFile jar = new JarFile(jarFile);
//返回zip文件条目的枚举
Enumeration<JarEntry> enumFiles = jar.entries();
JarEntry entry;
//测试此枚举是否包含更多的元素
while(enumFiles.hasMoreElements()){
entry = (JarEntry)enumFiles.nextElement();
if(entry.getName().indexOf("META-INF")<0){ //在字符串entry中查找"META-INF"首次出现的位置
String classFullName = entry.getName();
if(classFullName.indexOf(".class")<0){ //在字符串classFullName中查找".class"首次出现的位置
classFullName = classFullName.substring(0,classFullName.length()-1);
} else{
//去掉后缀.class
String className = classFullName.substring(0,classFullName.length()-6).replace("/", ".");
String strClassName=className.substring(className.lastIndexOf(".")+1, className.length());
System.out.println("最后截取的类名:" + strClassName);
Class<?> myclass = myClassLoader.loadClass(className);
//根据class对象获得属性
Field[] fields = myclass.getDeclaredFields(); //这里面获得了四个字段
Entities entitiesList = new Entities();
//获得类上的注解
FieldMeta meta111 = myclass.getAnnotation(FieldMeta.class);
System.out.println("类名的中文注释:" + meta111.name());
entitiesList.setEntityDesc(meta111.name()); //类名的中文描述(中文注释)
for(Field f1 : fields){
//获取字段中包含fieldMeta的注解
FieldMeta meta = f1.getAnnotation(FieldMeta.class);
System.out.println("打印长度:" + meta.length());
System.out.println("打印 类型:" + f1.getType().getName());
String getPropertyType = f1.getType().getName().toString();
String strPropertyType = getPropertyType.substring(getPropertyType.lastIndexOf(".")+1, getPropertyType.length());
System.out.println("最后截取的属性类型:" + strPropertyType);
if(meta!=null){
SortableField sf = new SortableField(meta, f1);
//System.out.println("字段名称:"+l.getName()+"\t字段类型:"+l.getType()+"\t注解名称:"+l.getMeta().name()+"\t注解描述:"+l.getMeta().description());
//System.out.println("字段名称:"+l.getName());
//将属性名和类名添加到实体中
entitiesList.setEntityName(strClassName); //类名
entitiesList.setDataType(strPropertyType); //属性类型
//entitiesList.setDataType(meta.getClass().getTypeName());
entitiesList.setDataLength(meta.length()); //长度
entitiesList.setPropertyName(f1.getName()); //属性名
entitiesList.setPropertyDesc(sf.getMeta().name()); //属性名的中文描述(中文注释)
entitiesBean.addJarToTable(entitiesList);
}
}
}
}
}
} catch(IOException e){
e.printStackTrace();
}
}【动态页面】(三)之二:通过自定义注解读取Jar包的类名和属性名
原文地址:http://blog.csdn.net/gaoying_blogs/article/details/44755991