文档章节

加强版ActionReporter,提升eclipse源代码定位功能

绝望的八皮
 绝望的八皮
发布于 2012/07/22 20:10
字数 903
阅读 3.8K
收藏 3

「深度学习福利」大神带你进阶工程师,立即查看>>>

 目前的的ActionReporter可以定位到当前方法调用过的Controller,点击eclipse控制台中的链接可以定位到改类的第一行,但是并不能直接定位到调用方法的那一行。

为了进一步提供开发者的体验,我加强了ActionReporter的源代码定位功能,能直接定位到调用的方法上面。先看下面效果图。 

 

当请请求调用了MobileBindController的heart方法,控制可以直接打出heart方法在 MobileBindController.java中的行数。

在java代码中虽然有能得到当前方法栈上的代码行数,但是由于jfinal中的aop并没有使用第三方的字节码工具修改原类的字节码,所有没有办法在方法调用之前知道要调用方法的行数。如果使用spring aop可以把这个功能切到目标方法调用的前面,应该可以达到效果。(没实际操作过还..)

在不修改字节码的情况下,我暂时只想到利用源码来计算行数..反正都是开发阶段,这样其实也无大碍..原理很简单.得到调用的类和方法然后到对应源文件去找该方法的字符串所在行。实现不够优雅但是功能还是挺实用的。

代码中删除字符串空格的方法直接copy自commons-lang。

代码再jdk7下编写的。7以下的需要把遍历文件那段代码稍微替换以下就ok了。

package com.jfinal.core;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.jfinal.aop.Interceptor;

/**
 * ActionReporter
 */
final class ActionReporter {
	
	private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	/**
	 * Report action before action invoking when the common request coming
	 */
	static final boolean reportCommonRequest(Controller controller, Action action) {
		String content_type = controller.getRequest().getContentType();
		if (content_type == null || content_type.toLowerCase().indexOf("multipart") == -1) {	// if (content_type == null || content_type.indexOf("multipart/form-data") == -1) {
			doReport(controller, action);
			return false;
		}
		return true;
	}
	
	/**
	 * Report action after action invoking when the multipart request coming
	 */
	static final void reportMultipartRequest(Controller controller, Action action) {
		doReport(controller, action);
	}
	
	private static final void doReport(Controller controller, Action action) {
		StringBuilder sb = new StringBuilder("\nJFinal action report -------- ").append(sdf.format(new Date())).append(" ------------------------------\n");
		Class<? extends Controller> cc = action.getControllerClass();
		sb.append("Controller  : ").append(cc.getName()).append(".(").append(cc.getSimpleName()).append(".java:")
		  .append(lineNum("publicvoid"+action.getMethodName()+"(){", fileName(cc))).append(")");
		sb.append("\nMethod      : ").append(action.getMethodName()).append("\n");
		
		String urlParas = controller.getPara();
		if (urlParas != null) {
			sb.append("UrlPara     : ").append(urlParas).append("\n");
		}
		
		Interceptor[] inters = action.getInterceptors();
		if (inters.length > 0) {
			sb.append("Interceptor : ");
			for (int i=0; i<inters.length; i++) {
				if (i > 0)
					sb.append("\n              ");
				Interceptor inter = inters[i];
				Class<? extends Interceptor> ic = inter.getClass();
				sb.append(ic.getName()).append(".(").append(ic.getSimpleName()).append(".java:")
				  .append(lineNum("publicvoidintercept", fileName(inter.getClass()))).append(")");
			}
			sb.append("\n");
		}
		
		// print all parameters
		HttpServletRequest request = controller.getRequest();
		@SuppressWarnings("unchecked")
		Enumeration<String> e = request.getParameterNames();
		if (e.hasMoreElements()) {
			sb.append("Parameter   : ");
			while (e.hasMoreElements()) {
				String name = e.nextElement();
				String[] values = request.getParameterValues(name);
				if (values.length == 1) {
					sb.append(name).append("=").append(values[0]);
				}
				else {
					sb.append(name).append("[]={");
					for (int i=0; i<values.length; i++) {
						if (i > 0)
							sb.append(",");
						sb.append(values[i]);
					}
					sb.append("}");
				}
				sb.append("  ");
			}
			sb.append("\n");
		}
		sb.append("--------------------------------------------------------------------------------\n");
		System.out.print(sb.toString());
	}

	private static String fileName(Class clazz) {
		String controllerFile = System.getProperty("user.dir")+File.separator+"src";
		for (String temp : clazz.getName().split("\\.")) {
			controllerFile = controllerFile+File.separator+temp;
		}
		return controllerFile+".java";
	}

	private static int lineNum(String codeFragment, String fileName) {
		List<String> lines = new ArrayList<>();
		int lineNum = 1;
		Path path = Paths.get(fileName);
		try {
			lines = Files.readAllLines(path, Charset.forName("utf-8"));
			for (int i = 0; i <lines.size(); i++) {
				String line = lines.get(i);
				if (codeFragment.equals(deleteWhitespace(line))) {
					lineNum=i+1;
					break;
				}
			}
		} catch(NoSuchFileException e1){
			// interceptor in jfinal.jar
		}
		catch (IOException e2) {
			e2.printStackTrace();
		}
		return lineNum;
	}
	
	 private static String deleteWhitespace(String str) {
	        if (isEmpty(str)) {
	            return str;
	        }
	        int sz = str.length();
	        char[] chs = new char[sz];
	        int count = 0;
	        for (int i = 0; i < sz; i++) {
	            if (!Character.isWhitespace(str.charAt(i))) {
	                chs[count++] = str.charAt(i);
	            }
	        }
	        if (count == sz) {
	            return str;
	        }
	        return new String(chs, 0, count);
	    }
	 
	 private static boolean isEmpty(CharSequence cs) {
	        return cs == null || cs.length() == 0;
	 }
}

 

 在目前官方jar中没有采用次java类的情况下,要使用这个功能的朋友请在自己的src下面建立com.jfinal.core包,放入和jar中同名的此类。

在类加载的时候classes会在lib之前加载,所以类加载器中加载的是我们改写过后的com.jfinal.core.ActionReporter

绝望的八皮

绝望的八皮

粉丝 392
博文 22
码字总数 10505
作品 2
其它
CTO(技术副总裁)
私信 提问
加载中
此博客有 10 条评论,请先登录后再查看。
Flappy Bird(安卓版)逆向分析(一)

更改每过一关的增长分数 反编译的步骤就不介绍了,我们直接来看反编译得到的文件夹 方法1:在smali目录下,我们看到org/andengine/,可以知晓游戏是由andengine引擎开发的。打开/res/raw/at...

enimey
2014/03/04
6.1K
18
我的架构演化笔记 功能1: 基本的用户注册

“咚咚”,一阵急促的敲门声, 我从睡梦中惊醒,我靠,这才几点,谁这么早, 开门一看,原来我的小表弟放暑假了,来南京玩,顺便说跟我后面学习一个网站是怎么做出来的。 于是有了下面的一段...

强子哥哥
2014/05/31
976
3
opm-server-mirror

代码更新 2009-11-25: 加入反爬虫功能。直接Web访问服务器将跳转到Google。 使用方法 下载index.zip 解压index.zip得到index.php 将index.php传到支持php和cURL的国外服务器上 打开 http:/...

luosheng86
2013/01/29
1K
0
C++模板库--C++ B-tree

这是一个google开源的C++模板库,实现了基于B-tree数据结构的有序内存容器。类似于STL的map、set、multimap和multiset模板,C++ B-tree也提供了btreemap、btreeset、btreemultimap和btreemu...

匿名
2013/02/05
3.4K
1
研究虚拟机--Jikes RVM

Jikes研究虚拟机(Jikes Research Virtual Machine,简称Jikes RVM)是一种成熟的用于执行Java程序的虚拟机,其早期版本与当前版本分别在通用公共许可证(CPL)与Eclipse公共许可证(EPL)下开...

匿名
2013/02/13
1.1K
0

没有更多内容

加载失败,请刷新页面

加载更多

您如何加速Eclipse? - How can you speed up Eclipse?

问题: How can you make the experience with Eclipse faster? 如何使Eclipse体验更快? For instance: I disable all the plugins I don't need (Mylyn, Subclipse, …). 例如: 我禁用了所......

fyin1314
15分钟前
9
0
百度地图SDK新版内测邀请

本文作者:用****9 百度地图开放平台为开发者提供七大基础服务能力,其中地图SDK和导航SDK是开发者广泛使用的重要基础服务,为了满足开发者更多使用需求以及提升开发者集成后的应用效果,本次...

百度开发者中心
前天
21
0
获取JavaScript数组中的所有唯一值(删除重复项) - Get all unique values in a JavaScript array (remove duplicates)

问题: I have an array of numbers that I need to make sure are unique. 我需要确定一个唯一的数字数组。 I found the code snippet below on the internet and it works great until th......

javail
今天
11
0
如何检查字符串是否为空? - How to check if the string is empty?

问题: Does Python have something like an empty string variable where you can do: Python是否有类似空字符串变量的内容可以在其中执行: if myString == string.empty: Regardless, wh......

富含淀粉
今天
19
0
您如何存储未跟踪的文件? - How do you stash an untracked file?

问题: I have changes to a file, plus a new file, and would like to use git stash to put them away while I switch to another task. 我对一个文件进行了更改,再加上一个新文件,并希......

技术盛宴
今天
39
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部