热搜:NVER node 开发 php

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

2024-11-10 17:05:01
【动态页面】(三)之二:通过自定义注解读取Jar包的类名和属性名_html/css_WEB-ITnose

    上篇博客介绍了通过反射读取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 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 list = new ArrayList();  		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 enumFiles = jar.entries();			JarEntry entry;						//测试此枚举是否包含更多的元素			while(enumFiles.hasMoreElements()){				entry = (JarEntry)enumFiles.nextElement();				if(entry.getName().indexOf("META-INF") 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包,有兴趣的可以下载下来试一试,有什么问题请在下方留言,欢迎和我沟通。