码迷,mamicode.com
首页 > 编程语言 > 详细

【动态页面】(三)之二:通过自定义注解读取Jar包的类名和属性名

时间:2015-03-30 21:11:53      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:jar   动态页面   读取jar包   自定义注解   

    上篇博客介绍了通过反射读取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包的类名、属性名包括中文注释和属性类型就都能实现了。我上传了一份Jar包:http://download.csdn.net/detail/huanjileaimeidan/8548345  这个是我上传上去可以进行测试的Jar包,有兴趣的可以下载下来试一试,有什么问题请在下方留言,欢迎和我沟通。


【动态页面】(三)之二:通过自定义注解读取Jar包的类名和属性名

标签:jar   动态页面   读取jar包   自定义注解   

原文地址:http://blog.csdn.net/gaoying_blogs/article/details/44755991

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!