java Web调试神器
javaWeb 工作者因页面不断的跳来跳去,不断的重启服务器,收参收不到,空指针异常,不给力的日志信息似乎还不如用System.out.print 好用,为此, 为了清楚的监视java的执行流程我写了两个文件 M.java与M.jsp
都是用于参数的查看的,M.java用在java代码里, M.jsp是一个servlet版的<s:debug/>用于不断监视作用域里的数据,与收到的参数信息,用在springMvc简直是绝配,用法就是将该jsp放在jsp页面末尾。
,其中M.java支持M.properties配置与注解配置,M.jsp直接在页面上显示是否使用
M.java
1 package minglie.utils; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.lang.annotation.Annotation; 8 import java.lang.annotation.ElementType; 9 import java.lang.annotation.Retention; 10 import java.lang.annotation.RetentionPolicy; 11 import java.lang.annotation.Target; 12 import java.lang.reflect.AccessibleObject; 13 import java.lang.reflect.Array; 14 import java.lang.reflect.Field; 15 import java.lang.reflect.Method; 16 import java.util.Arrays; 17 import java.util.List; 18 import java.util.Properties; 19 import java.util.Random; 20 21 /** 22 * 此类写一些实用的通用的方法-V0.2 23 * @author Administrator 24 */ 25 public class M { 26 //////////////////////////////////////////////////////////////////////////////////// 27 /////////////////////////调试神器/////////////////////////////////////////////////////////// 28 //除了这些来关每个类还有注解开关,不加注解默认所有开关均开启,加注解@MingConfig则不能打印, 29 //@MingConfig("in")说明只能打印输入信息@MingConfig("in out")说明只能打印输出信息 30 //这些配置也可以通过properties文件进行配置 31 public static int CON_ENABLE;// 总开关 32 public static int CON_W_ENABLE;// 参数打印使能 33 public static int CON_IN_ENABLE;// 方法进入打印使能 34 public static int CON_OUT_ENABLE;// 方法退出打印使能 35 36 //自定义注解可以出现的位置,为了使打印配置更为灵活 37 @Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) 38 @Retention(RetentionPolicy.RUNTIME) 39 public @interface MingConfig{ 40 String value() default "in out w"; 41 } 42 43 /** 44 * 函数进入打印信息 45 */ 46 public static void in(Object... param) { 47 Throwable t = new Throwable(); 48 Class clazz=null; 49 try { 50 clazz = Class.forName(t.getStackTrace()[1].getClassName()); 51 } catch (ClassNotFoundException e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 } 55 List<String> list=AnnotationHelper.getMingConfigInfo(clazz); 56 if ( (list==null||list.contains("in")) && M.CON_IN_ENABLE == 1 && CON_ENABLE == 1) { 57 System.out.println(); 58 System.out.print("------------进入"); 59 System.out.print(t.getStackTrace()[1].getClassName() + "."); 60 System.out.println(t.getStackTrace()[1].getMethodName() + "------"); 61 if (param.length > 0) { 62 for (int i = 0; i < param.length; i++) { 63 System.out.println("[in:" + i + "]==> " + param[i]); 64 } 65 } 66 System.out.println(); 67 } 68 } 69 70 /** 71 * 函数退出打印信息 72 */ 73 public static void out(Object... param) { 74 Throwable t = new Throwable(); 75 Class clazz=null; 76 try { 77 clazz = Class.forName(t.getStackTrace()[1].getClassName()); 78 } catch (ClassNotFoundException e) { 79 // TODO Auto-generated catch block 80 e.printStackTrace(); 81 } 82 List<String> list=AnnotationHelper.getMingConfigInfo(clazz); 83 if ( (list==null||list.contains("out")) && M.CON_OUT_ENABLE == 1 && CON_ENABLE == 1) { 84 if (param.length > 0) { 85 for (int i = 0; i < param.length; i++) { 86 System.out.println("[out:" + i + "]==> " + param[i]); 87 } 88 } 89 System.out.print("------------退出"); 90 System.out.print(t.getStackTrace()[1].getClassName() + "."); 91 System.out.println(t.getStackTrace()[1].getMethodName() + "------"); 92 System.out.println(); 93 } 94 } 95 /** 96 * 打印信息 97 */ 98 @SuppressWarnings("unused") 99 public static void w(Object... param) { 100 Throwable t = new Throwable(); 101 Class clazz=null; 102 try { 103 clazz = Class.forName(t.getStackTrace()[1].getClassName()); 104 } catch (ClassNotFoundException e) { 105 // TODO Auto-generated catch block 106 e.printStackTrace(); 107 } 108 List<String> list=AnnotationHelper.getMingConfigInfo(clazz); 109 if ( (list==null||list.contains("w")) && M.CON_W_ENABLE == 1 && CON_ENABLE == 1) { 110 if (param.length > 0) { 111 for (int i = 0; i < param.length; i++) { 112 System.out.println("[w:" + i + "]==> " + param[i]); 113 } 114 } 115 } 116 } 117 /** 118 * 根据反射构造toString,List不是Array,所以不能打印List,此函数适合打印基本类型数组,或属性为基本类型的对象 119 */ 120 @SuppressWarnings("unused") 121 public static void rw(Object... param) { 122 Throwable t = new Throwable(); 123 Class clazz=null; 124 try { 125 clazz = Class.forName(t.getStackTrace()[1].getClassName()); 126 } catch (ClassNotFoundException e) { 127 e.printStackTrace(); 128 } 129 List<String> list=AnnotationHelper.getMingConfigInfo(clazz); 130 if ( (list==null||list.contains("w")) && M.CON_W_ENABLE == 1 && CON_ENABLE == 1) { 131 if (param.length > 0) { 132 for (int i = 0; i < param.length; i++) { 133 System.out.println("[rw:" + i + "]==> " + GeneralToString.toString(param[i])); 134 } 135 } 136 } 137 } 138 139 140 141 142 /** 143 * 注解测试 144 * @param param 145 */ 146 public static void t1(Object... param) { 147 Throwable t = new Throwable(); 148 Class clazz=null; 149 try { 150 clazz = Class.forName(t.getStackTrace()[1].getClassName()); 151 } catch (ClassNotFoundException e) { 152 e.printStackTrace(); 153 } 154 String methodName = t.getStackTrace()[1].getMethodName(); 155 System.out.println(methodName+" "+clazz); 156 157 Method[] m1Method=null; 158 try { 159 m1Method = clazz.getMethods(); 160 } catch (SecurityException e1) { 161 e1.printStackTrace(); 162 } 163 System.out.println(m1Method[0]); 164 165 List<String> list=AnnotationHelper.getMingConfigInfo(m1Method[0]); 166 System.out.println(list); 167 } 168 169 170 171 172 //////////////////////////////////////////////////////////////////////////////////// 173 //////////////////////////////////////////////////////////////////////////////////// 174 //////////////////////////////////////////////////////////////////////////////////// 175 //////////////////////////////////////////////////////////////////////////////////// 176 //////////////////////////////////////////////////////////////////////////////////// 177 //////////////////////////////////////////////////////////////////////////////////// 178 //////////////////////////////////////////////////////////////////////////////////// 179 /** 180 * 产生digCount随机数 181 */ 182 public static String getRandomNumber(int digCount) { 183 Random rnd = new Random(); 184 StringBuilder sb = new StringBuilder(digCount); 185 for (int i = 0; i < digCount; i++) 186 sb.append((char) ('0' + rnd.nextInt(10))); 187 return sb.toString(); 188 } 189 190 191 /** 192 * 通配符的实现,本函数仅仅是将str里的? 强行替换成 param里的值,在用与sql语句时,如果有必要应在str里添加单引号 193 * 194 * @param str 195 * @param param 196 * @return 返回替换后的字符串 197 */ 198 public static String p(String str, Object... param) { 199 String result = ""; 200 if (param.length > 0) { 201 StringBuilder sb = new StringBuilder(); 202 int i = 0, j = 0; 203 // 如果str里面有"?",将其位置赋给i 204 while ((i = str.indexOf("?")) != -1) { 205 sb.append(str.substring(0, i) + param[j++].toString()); 206 str = str.substring(i + 1); 207 } 208 sb.append(str); 209 result = sb.toString(); 210 } else { 211 result = str; 212 } 213 return result; 214 } 215 216 217 218 /** 219 * 静态加载配置文件 220 */ 221 private static Properties prop; 222 static{ 223 //不存在返回null 224 InputStream is=M.class.getResourceAsStream("/M.properties"); 225 try { 226 //创建出Properties对象 227 prop=new Properties(); 228 if(is !=null) prop.load(is); 229 else prop=null; 230 } catch (Exception e) { 231 // TODO Auto-generated catch block 232 e.printStackTrace(); 233 }finally{ 234 try { 235 if(is !=null)is.close(); 236 } catch (IOException e) { 237 // TODO Auto-generated catch block 238 e.printStackTrace(); 239 } 240 } 241 } 242 243 /** 244 * 初始化配置参数 245 */ 246 static{ 247 //System.out.println(prop); 248 String str=""; 249 try{ 250 if(prop !=null){ 251 str=propertiesRead("CON_ENABLE"); 252 if(str !=null && str.equals("0")){ 253 CON_ENABLE=0; 254 }else{ 255 CON_ENABLE=1; 256 } 257 258 str=propertiesRead("CON_W_ENABLE"); 259 if(str !=null && str.equals("0")){ 260 CON_W_ENABLE=0; 261 }else{ 262 CON_W_ENABLE=1; 263 } 264 265 str=propertiesRead("CON_IN_ENABLE"); 266 if(str !=null && str.equals("0")){ 267 CON_IN_ENABLE=0; 268 }else{ 269 CON_IN_ENABLE=1; 270 } 271 272 str=propertiesRead("CON_OUT_ENABLE"); 273 if(str !=null && str.equals("0")){ 274 CON_OUT_ENABLE=0; 275 }else{ 276 CON_OUT_ENABLE=1; 277 } 278 }else{ 279 CON_ENABLE=1; 280 CON_W_ENABLE=1; 281 CON_IN_ENABLE=1; 282 CON_OUT_ENABLE=1; 283 } 284 }catch(Exception e){ 285 e.printStackTrace(); 286 } 287 //M.w(CON_ENABLE,CON_W_ENABLE,CON_IN_ENABLE,CON_OUT_ENABLE); 288 } 289 290 291 292 /** 293 * 读取M.properties中键对应的值 294 */ 295 public static String propertiesRead(String key) { 296 if(prop==null) return null; 297 String value = prop.getProperty(key); 298 return value; 299 } 300 } 301 302 303 /** 304 * 此类是为了获取类上,或方法上的注解信息 305 * @author Administrator 306 * 307 */ 308 class AnnotationHelper{ 309 /** 310 * 得到类中或方法中的注解信息 311 * @param obj 为一个方法或一个类 312 * @return 313 */ 314 @SuppressWarnings("unchecked") 315 public static List<String> getMingConfigInfo(Object obj){ 316 Annotation annotation=null; 317 List<String> result=null; 318 319 if(obj instanceof Class){ 320 annotation = ((Class)obj).getAnnotation(M.MingConfig.class); 321 }else if(obj instanceof Method){ 322 annotation = ((Method)obj).getAnnotation(M.MingConfig.class); 323 } 324 325 if(annotation != null){ 326 M.MingConfig mi=(M.MingConfig)annotation; 327 result=Arrays.asList(mi.value().split(" ")); 328 } 329 return result; 330 } 331 332 333 334 } 335 336 337 338 339 /** 340 * 利用反射写的一个通用的toString方法,没有递归到基本类型,当类的属性为对象时,改对象应改有toString方法 341 */ 342 class GeneralToString { 343 public static String toString(Object obj) { 344 String result = "null"; 345 StringBuffer strBuf = new StringBuffer(); 346 Class<? extends Object> cla = obj.getClass(); 347 /** 348 * 对于基本数据类型和String直接返回 349 */ 350 if (cla == Integer.class || cla == Short.class || cla == Byte.class 351 || cla == Long.class || cla == Double.class 352 || cla == Float.class || cla == Boolean.class 353 || cla == String.class || cla == Character.class) { 354 strBuf.append(obj); 355 result = strBuf.toString(); 356 } 357 /** 358 * 对数组类型的处理 359 */ 360 if (result.equals("null") && cla.isArray()) { 361 strBuf.append("["); 362 for (int i = 0; i < Array.getLength(obj); i++) { 363 if (i > 0) 364 strBuf.append(","); 365 Object val = Array.get(obj, i); 366 367 if (val != null && !val.equals("")) { 368 strBuf.append(val.toString()); 369 } 370 } 371 strBuf.append("]"); 372 result = strBuf.toString(); 373 } 374 if (result.equals("null")) { 375 // 获取所有属性 376 Field[] fields = cla.getDeclaredFields(); 377 // 设置所有属性方法可访问 378 AccessibleObject.setAccessible(fields, true); 379 String className=cla.toString(); 380 381 className=className.substring(className.lastIndexOf(".")+1); 382 383 strBuf.append(className+" ["); 384 for (int i = 0; i < fields.length; i++) { 385 Field fd = fields[i]; 386 strBuf.append(fd.getName() + "="); 387 try { 388 if (!fd.getType().isPrimitive() 389 && fd.getType() != String.class) { 390 if (fd.get(obj) != null) { 391 strBuf.append(fd.get(obj).toString()); 392 }else{ 393 strBuf.append("null"); 394 } 395 } else { 396 strBuf.append(fd.get(obj)); 397 } 398 } catch (Exception e) { 399 e.printStackTrace(); 400 } 401 if (i != fields.length - 1) 402 strBuf.append(", "); 403 } 404 strBuf.append("]"); 405 } 406 407 return strBuf.toString(); 408 } 409 410 }
M.jsp
<%-- <%@include file="/M.jsp"%> //静态引入 ${pageContext.request.contextPath} //项目路径 将第1行的指令放在jsp页面的最后一行 它将随时观察作用域的数据 包括 请求参数 与 转发 参数 和 作用域的参数 --%> <%@ page language="java" import="java.util.*"%> <%@ page contentType="text/html;charset=utf-8"%> <%! public static final int CON_JSP_ENABLE = 1; // JSP开关 public static final int CON_CONSOLE_ENABLE = 0;//控制台开关 public void w(Object o){ if(CON_CONSOLE_ENABLE==1){ System.out.print(o); } } public void wln(Object o){ if(CON_CONSOLE_ENABLE==1){ System.out.println(o); } } %> <div <% if(CON_JSP_ENABLE==0) out.println("style=display:none"); %> > <br/><br/><hr/> <% request.setCharacterEncoding("utf-8"); %> <% response.setCharacterEncoding("utf-8"); %> 提交方式:<%=request.getMethod() %> <hr/> 请求的URL:<%=request.getRequestURL() %> <hr/> <p style="color: red">请求的参数</p> <% wln( "提交方式:"+request.getMethod()); wln( " 请求的URL:"+request.getRequestURL() ); wln( " 请求的参数:" ); Enumeration enu=request.getParameterNames() ; while(enu.hasMoreElements()){ String paraName=(String)enu.nextElement(); out.println(paraName+": "); w(paraName+": "); String val=request.getParameter(paraName); String[] strs=request.getParameterValues(paraName); if(strs.length>1){ for(String s:strs){ out.println(s); wln(s); } }else{ out.println(val); wln(val); } out.println("<br/>"); } wln("---------------------------------"); %> <hr/> <p style="color: red">request的作用域</p> <% Enumeration enu1= request.getAttributeNames(); wln("request的作用域"); while(enu1.hasMoreElements()){ Object paraName=enu1.nextElement(); if(paraName instanceof String){ Object val=request.getAttribute((String)paraName); if(paraName.toString().length()<20){ out.println(paraName+": "); w(paraName+": "); out.println(val); wln(val); out.println("<br/>"); out.println("<br/>"); } } } out.println(); out.println(); wln("----------------request信息输出完成----------------"); %> <hr/> <p style="color: red">session的作用域</p> <% Enumeration<String> enu2 = session.getAttributeNames(); wln("session的作用域"); while(enu2.hasMoreElements()){ String paraName=enu2.nextElement(); Object val=session.getAttribute(paraName); out.println(paraName+": "); w(paraName+": "); out.println(val); wln(val); out.println("<br/>"); } out.println(); out.println(); wln("----------------session信息输出完成----------------"); %> <hr/> <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> </div>
浙公网安备 33010602011771号