您的位置:首页 > Web前端 > JavaScript

JSP 快速展示数据

2009-09-13 17:32 246 查看
小弟 2004 年学 MS Classic ASP 最老的那种 ASP,非 Net。到现在开始,正式使用 JSP。虽然小弟之前很早就接触 Java 了,大概知道一点点,却又不尽然。因此,JSP,还是要边学边用。是以为笔记吧。

了解 Tomcat

Tomcat 是 HTTP Server,也是 Web 容器。Tomcat 由以下的组件所构成:

Catalina (servlet container,所谓 Servlet,应该就是今天Web 框架里面的 Route、分发之类的问题),
Coyote (an HTTP connector 处理 HTTP 头和响应头的底层包)

Jasper (a JSP engine,说穿了就是一个模版系统)
开发者从对 Java 的热爱延伸到对 JSP 的热爱,同时 JSP 也是 J2EE 体系中最重要,而且又是最基础的一个组成部分,如果要体验 J2EE 带了的开发效率和优势,JSP 会是非常有效的入门方式。学习、使用 JSP 的好处如下:
JSP 程序容易上手,如果有 HTML 和 Java 的基本知识,或者接触过 ASP/PHP 的话,那么学习 JSP 程序就没有任何难度。
JSP 就是在 HTML 中嵌入 Java 代码,所以在本质上 JSP 程序就是 Java 程序,JSP 程序继承了Java 的一切优点(注,除了内部类稍有不同)。JSP 程序有严格的 Java 类库支持。JSP 页面在服务器中都会被 JSP 编译器编码称对应的 Servlet。
JSP 中可以使用 Java Bean 进行逻辑封装,这样就可以实现逻辑功能代码的重用,即经典的 Bean + Servlet + JSP,从而大大提高系统的可重用性,同时也提高了程序的开发效率。
新版 Eclipse 4.2 完全做到对 JSP 开发给力的支持,包括错误校验、智能提示、调试等强大的辅助功能,甚至 include 文件的上下文都可支持。

最重要的一点,JSP 不需要重启服务器!
请看官参阅以下网友资源:
java框架太多,感觉太复杂。web应用直接用Jsp+Servlet+JavaBean不是更简单?而且更灵活实际上依然有公司在用纯Jsp 的script的形式写项目。
我觉得应用框架最大的作用就是尽量让项目变得灵活,同时让程序员不要那么灵活。因为项目灵活才能适应客户的需求变更,程序员加上框架的限制能够降低人员流动的成本。框架就像马鞍,给马套上框架不是为了让马更舒服,而是为了骑马的人更舒服。
bbs.csdn.net/topics/360099689
另外,坦率的说,此框架可能更适合有“经验”的开发人员,更适合开发需要复杂视觉表现力的产品级项目。对于真正实战用过Struts,JSF,Tapestry,Turbine,Webwork等框架的朋友,相信会找到一种久违的“自由”感觉。

敏捷开发,一个很老很年轻的话题,不得不谈而且必须谈的话题,无论你用ASP、PHP、JSP还是ROR,它随时都触动我们开发的神经,让我们在懵懵焦虑中度过一个个不眠之夜。困了,烦了,唉......与其在烦恼中困惑,不如在烦恼中爆发,让我们展开JSP敏捷开发的畅想吧!
……

泛组件化是敏捷开发的最大陷阱!我们的WEB必须要有视觉表现力,WEB2.0要求更甚,但这种表现力需要精烹细调,个中过程远非简单的HTML、CSS之类,开发人员随时可能更改程序部分,不仅仅美工的问题,如果更改部分是“组件”,那你的麻烦大了
……
WEB特色来自handy,而非component!为何ASP、PHP以及新近出现的ROR,无一例外都把JSP打的满地找牙?随便找三点原因:
1. 解释性语言简单明了,学习、开发、维护成本都很低廉,让J***A学究式语言的规范整洁无用武之地。
2. WEB开发无需大量企业级应用组件,一般提供mysql编程接口即可,这让J***A的海量组件形同虚设。
3. 语言本身决定了单纯动态页面的编码难度。排除语言本身的优势,VBS,PHP,RUBY相对都很简单,说白了,能完成简单逻辑和mysql编程即可。
再来看看RoR为何近年来很火!?它是OO类语言,这是潮流,看看这两年C#和PHP5都在OO方面大力跟进就知道了,但为何只有RoR有排山倒海之势呢?!甚至出现了Grails跟风。另外,后者会上演GoG大戏吗?因为它有Java这个OO鼻主当靠山啊。No,回答是否定的,原因何在呢?回答这个问题前,得先回答另外一个问题:如果没有Rails,Ruby还翱翔的翅膀吗?除了语言本身的简洁,Rails最大的特点就是:习惯约定优于配置。所以,与其说Ruby,还不如说是Rails给WEB开发带来了暂新的模式。正是这个满足八二原则的开发模式极大激发了WEB开发人员的热情。尤其是Java开发人员,他们身负“组件化”重任,饱受各种配置规范的折磨,这种handy风格让他们看到了解脱的希望。假如将这种handy风格应用到Jsp,又会出现怎样的情形?问题是Jsp是烂泥吗?能扶上墙吗?答案是:能!针锋相对的理由:
1. 语言规范整洁,符合企业严整风范
2. 超大规模的企业级应用组件,便于web应用未来扩大之后的进一步发展
3. 单纯JSP页面只包含显示逻辑,在IDEA、Ellipse插件支持下也能展开敏捷开发
http://www.jdon.com/33785
你可以说可爱的php ,可爱的ror ,可爱的python ,甚至可爱的.net ,但是javaee ?他太复杂了。相比前三种技术,javaee 的技术体系更全面、更规整也更复杂,他的复杂性也让很多厂商望而止步,宁可选择简单甚至简陋的php ,这充分说明快速开发是这个时代最迫切的需求。

javaee 的servlet 、javabean 、jdbc 规范给了我们组件和容器的唯一标准,而更高级的支持,jsf 、jdo 规范却没能给予我们唯一的框架级标准,他们被认可的程度远低于相同领域的开源框架。尽管开源社区给了我们最丰富的选择,但是相比.net 、php 、ror 的全栈式服务,javaee 开发者必须DIY 。DIY 不但需要时间而且需要冒险,这种发烧友做的事情是企业所不愿意做的。一段时间以来,公司javaee 方向的招聘几乎清一色的要求struts 、spring 、hibernate 这几种主流框架的能力就是一种证明。
……
“任何优秀的语言,都可以帮助开发者写出优秀的代码,但不能阻止开发者写出糟糕的代码”。在这一点上,无论是javaee ,.net ,ror ,php 都不会例外。而开发框架就像是“一间有很多屋梁的房子”,“框架的强大之处不是他能让你做什么,而是他不能让你做什么”,其实如同语言一样,框架虽然可以给予开发一定程度的规范指导,但是这种指导仍然是有限的,这真应了那句老话:事在人为。
http://javaonejcy.iteye.com/blog/505128
《使用spring-loaded 提高java 应用开发效率 》
在 web 应用开发领域,java 平台相比较其它脚本语言有明显的性能优势。但在 java 平台开发 web 应用有一个缺点就是频繁系统重启带来的开发效率下降。php 之类的脚本语言开发 web 应用时都可以做到“click,refresh”的开发流程,代码修改后刷新立即就可以看到结果。java web 应用往往需要编译-重启-刷新,在这个过程中,重启是最耗时的环节,如果项目比较大或者使用了一些重量级的应用服务器,重启耗时更为明显。
虽然 jvm 提供了一定程度的代码替换功能,但有很大局限,仅能修改方法实现代码。某些应用服务器(例如 jetty)也提供了类的热加载功能,但经常会出现 PermGen OOM 错误,这些解决方案都不太理想。

总之,一个工具如果使用的好,取其长而去其短,自然可以飞花摘叶皆可伤人。
另请参阅 :
《极简风格Web架构,jsp+jdbc的二次复辟》http://www.blogjava.net/calvin/archive/2008/07/31/218903.html
https://github.com/spring-projects/spring-loaded
http://jinnianshilongnian.iteye.com/blog/1887788
一个例子,保存数据库:
先设置头内容:

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="java.sql.*" %>
再写 J***A 代码,既有 class 部分,也有直接写 Java 的:

class Connect {
	public Connection getConn(String driver, String jdbcUrl, java.util.Properties props){
		Connection conn = null;
		
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			System.out.println("创建数据库连接失败,请检查是否安装对应的 Driver"); 
			e.printStackTrace();
		}
		
		try {
			if(props == null){
				conn = DriverManager.getConnection(jdbcUrl);
			}else{
				conn = DriverManager.getConnection(jdbcUrl, props);
			}
			System.out.println("数据库连接成功:" + conn);
		} catch (SQLException e) {
			System.out.println("数据库连接失败!"); 
			e.printStackTrace();
		}
		return conn;
	}
	
	//demo
	public Connection getConnSqlite(){
		return getConn("org.sqlite.JDBC", "jdbc:sqlite:D:\\yuetv2014.sqlite", null);
	}
}

Connection conn = new Connect().getConnSqlite();
System.out.println(conn.getMetaData().getURL());
Statement statement = conn.createStatement();
String name 	= new String(request.getParameter("name").getBytes("iso-8859-1"), "UTF-8");
String contact	= new String(request.getParameter("contact").getBytes("iso-8859-1"), "UTF-8");
String msg		= new String(request.getParameter("msg").getBytes("iso-8859-1"), "UTF-8");

name = "('" + name + "',";
contact = "'" + contact + "',";
msg = "'" + msg + "')";

String sql = "INSERT INTO freeback (name, contact, msg) VALUES " + name + contact + msg;

System.out.println(sql);

try{
	statement.execute(sql);
	out.write("<script>alert('提交成功!');history.go(-1);</script>");
}catch(Exception e){
	e.printStackTrace();
	out.write("<script>alert('提交失败!');history.go(-1);</script>");
}finally{
	statement.close();
	conn.close();
}

内置对象

JSP 页面内置对象,这都是自带的、默认的,每张 JSP页面都会提供的。和 ASP 类似,它们是:
ASPJSP
返回服务端的一些信息Server实际类型:
org.apache.catalina.core.StandardWrapperFacadeStandardWrapperFacade
实现接口javax.servlet.ServletConfig
page
实际类型:org.apache.jsp.index_jspindex_jsp
继承类org.apache.jasper.runtime.HttpJspBaseHttpJspBase
继承类javax.servlet.http.HttpServlet

程序作用域下的全局对象Application实际类型:
org.apache.catalina.core.ApplicationContextFacadeApplicationContextFacade
实现接口javax.servlet.ServletContext
客户端的请求Request实际类型:
org.apache.catalina.connector.RequestFacadeRequestFacade

实现接口javax.servlet.http.HttpServletRequest
e.g:String username=request.getParameter("username");
if(username.equals(""))...

响应客户端Response实际类型:
org.apache.catalina.connector.ResponseFacadeResponseFacade
实现接口javax.servlet.http.HttpServletRequest
response.sendRedirect(...);

会话Seesion实际类型:
org.apache.catalina.session.StandardSessionFacadeStandardSessionFacade
实现接口javax.servlet.http.HttpSession
页面上下文ObjectContextpageContext
实际类型:
org.apache.jasper.runtime.PageContextImplPageContextImpl
继承类javax.servlet.jsp.PageContext
异常exception
这方面应该多差文档,例如官方的就不错。待项目深入逐渐学习各个 API 之用法。

插入 HTML 片断 / 标签复用

最简单的一种 <%@ include file="public/class.jsp" %>,ASP 和 JSP 写法一样。

不过和 ASP 不一样,不能在方法中混搭 HTML,如下面的是不行的哦:

<% public static voidgetFooter(){
%>
 <div>...</div>
<%
}
%>
于是,得使用 JSP 标签。最妙的是可以使用 <%=var%> 读取上下文变量。

<jsp:include page="bar.jsp" >
    <jsp:param name="extraparam" value="TestTest" />
    <jsp:param name="extraparam2" value="<%=a%>" />
</jsp:include>
被 include 页面,用 $ 读取参数:
888-----------${param.extraparam}------${param.extraparam2}-------888
虽然 JSP 页面不如 ASP 那般灵活,但好在每个 include 页面都是独立的上下文,此时可以通过 request、session、application 等作用域共享的对象作为中介媒体,传递对象。它们本质上 map,因此可以通过 setArrtibute() 方法设置任意类型的对象。如下所示:
<% 
  String name="zhouhaigang";
  request.setAttribute("name", name);
%>

${ name }
更复杂一些数据类型……

// jsp页面开头要导入你的User类。 
List<User> userList = (List<User>)request.getAttribute("你传来的List");
int len = userList.size();
for(...){
  ...
}

导入 JAR / Classes

使用已编译的 Class:按照命名空间放置 *.class 文件在 WEB-INF/Classes 目录下。然后 JSP 中使用 import iori.db 调用
使用 JAR 包(JAR包就是包含很多 Class 的集合):一般情况下,放到WEB-INF/lib下就可以了,这也是推荐的做法;实在不行就放到/Tomcat /common/lib下,不过会启动服务器就自动加载的,但是太多了影响启动速度。最后就是在 JSP 中引入 <%@ page import="Com.bbpoint.Connect.*" %><jsp:useBean id="asd" scope="page" class="connect.Connect" />。这样前提 JAR 包中有相对应的类。JAR 是 ZIP 压缩包,用 7zip 之类的工具可以浏览。未知 JAR 包,要了解其 API 的话,最好用 Eclipse 或者反编译的手段。

下面包为什么不需要通过 Class/ JAR,引入就可以在 JSP 页面中直接使用?
<%@page   import="java.sql.Connection"%>
<%@page   import="java.sql.DriverManager"%>
<%@page   import="java.sql.Statement"%>
<%@page   import="java.sql.ResultSet"%>
答案:因为 tomcat 已经通过系统环境变量 Classpath 获取到你的 JDK/JRE 的包,所以直接 import 就可以了。
如何编译一个 Class 呢?好处是别人不会轻易地看到你的代码!
详见该文《Tomcat+JSP经典配置实例 》,写得不错哦。

JSP 中如何定义一个方法或类

要定义方法,必须在 <% 后加个感叹号 !
<%!   //此处有感叹号  

private   void   aMethod(){ 
...;   
}  
// 也可以是属性
private   String   aVariableOfClassScope; 
……
%>
这样的做法相当于在 Servlet 中重新定义了一个方法;如果没感叹号,就是普通的那种情况,那表示在 Servlet.doService() 方法写逻辑,你在生成的 java 类中看到混搭 HTML / Java 的代码。
<%   
   //此处无感叹号,代码将会在 doService() 方法中
   ...; 
%> 
奇怪的是类也可以写在 doService() 方法中????

捕获异常

设置可以捕获代码中显式抛出的异常:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" errorPage="error.jsp"%>
接收异常的页面
<%@page isErrorPage="true"%>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>JSP Page</title>
</head>
<body>
	Error~!
	<%=exception.getMessage()%></body>
</html>
对于未知的、非捕获的异常也就是 500 出错,应该用 tomcat 的 500 err 代码跳转,但却又不利于调试,怎么两者都兼顾呢?
调试手段:
System.out.println("676"+uid_Str);

mylist.getClass().getName();

out.write(str);

设置 Tomcat 兼容中文 url:
在 Server.xml 中加入的 Connector 节点中加入 URIEncoding="UTF-8" 属性:

<Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="UTF-8" />


去除JSP页面自动生成的空行 加入 <%@ page trimDirectiveWhitespaces="true" %>
----------------------------

输出 J***A 变量,代替 <%=%>,这样就不会因为JSP inchuld 找不到上下文而让 Eclipse 报错了。

<jsp:expression>Global_WebRoot</jsp:expression>
---------------------------
JSP Mapping

<servlet>
<servlet-name>live_detail</servlet-name>
<jsp-file>/live/detail.jsp</jsp-file>
</servlet>

<servlet-mapping>
<servlet-name>live_detail</servlet-name>
<url-pattern>/live/detail</url-pattern>
</servlet-mapping>
JSP 的路径 按照 URL 的虚拟路径为准,包括 <%@ include file="../../public/head.jsp" %> 都如是。

参阅

《为什么JSP的内置对象不需要声明》
《用TOMCAT作简单的jsp web开发》
《JSP 原理和 Tomcat 配置》
《Tomcat+JSP经典配置实例》 编写自己的 Class
Unknow
利用 JSP 2 提供的 SimpleTagSupport 开发自定义标签
为 JSP 文件。
头引用是:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ page import="java.net.*, java.util.*, java.io.*"%>

JSP 内容:

// 跨域用代理
request.setCharacterEncoding("UTF-8");
String url = null;
StringBuffer params = new StringBuffer();
Enumeration enu = request.getParameterNames();
int total = 0;
while (enu.hasMoreElements()) {
	String paramName = (String)enu.nextElement();
	if(paramName.equals("url")){
	  url = request.getParameter(paramName);
	}else{
	  if(total == 0){
	  	params.append(paramName).append("=").append(URLEncoder.encode(request.getParameter(paramName), "UTF-8"));
	  } else {
	  	params.append("&").append(paramName).append("=").append(URLEncoder.encode(request.getParameter(paramName), "UTF-8"));
	  }

	  System.out.println("paramName:" + paramName + "/" + request.getParameter(paramName)); 
	  ++total;
	}
}
String param = params.toString();

// out.println(url);
if(url != null){
	// 使用GET方式向目的服务器发送请求
	URL connect = new URL(url);
	HttpURLConnection connection = (HttpURLConnection)connect.openConnection();
	connection.setConnectTimeout(3000);  
	connection.setReadTimeout(3000);  
	connection.setDoOutput(true);
	connection.setDoInput(true);
	connection.setUseCaches(false);  
	connection.setRequestMethod("POST");
	connection.setRequestProperty("Content-type","application/x-www-form-urlencoded;charset=utf-8");
	
	connection.connect();

	System.out.println("url:" + url); 
	System.out.println("para:" + param); 
 
 	OutputStream os = connection.getOutputStream();  
    os.write(param.getBytes()); 
	os.flush();
	os.close();

    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));

	String line;
	while((line = reader.readLine()) != null){
	  out.println(line);
	}
	reader.close();
}

附详尽注释的 jsp,可支持 GET/POST:

<%@ page import="java.util.Enumeration"%>
<%!
// java.io.*,java.net.*
// 使用GET方式向目的服务器发送请求
public static String HTTPRequest(String url) throws IOException{
    String result = "", line;
	// 拼凑get请求的URL字串,使用URLEncoder.encode对特殊和不可见字符进行编码
	// String getURL = GET_URL + "&activatecode=" + URLEncoder.encode(url);
    URL getUrl = new URL(url);
    // 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection
    HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
    // 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到服务器
    connection.connect();
    // 取得输入流,并使用Reader读取,并设置编码,否则中文乱码
    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));

    while ((line = reader.readLine()) != null){
    	result += line;
    	// lines = new String(line.getBytes(), "utf-8");
        // System.out.println(line);
    }

    // System.out.println(result);

    reader.close();
    connection.disconnect();// 断开连接

    return result;		
}

// 使用 POST 方式向目的服务器发送请求
public static String HTTPPost(String url, String params) throws IOException{
	String result = "", line;
	
	URL connect = new URL(url);
	HttpURLConnection connection = (HttpURLConnection)connect.openConnection();
	connection.setConnectTimeout(3000);  
	connection.setReadTimeout(3000);  
	connection.setDoOutput(true);
	connection.setDoInput(true);
	connection.setUseCaches(false);  
	connection.setRequestMethod("POST");
	connection.setRequestProperty("Content-type","application/x-www-form-urlencoded;charset=utf-8");
	
	connection.connect();

	System.out.println("url:" + url); 
	System.out.println("para:" + params); 
 
 	OutputStream os = connection.getOutputStream();  
    os.write(params.getBytes()); 
	os.flush();
	os.close();

    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));

	while((line = reader.readLine()) != null){
		result += line;
		// out.println(line);
	}
	reader.close();

	return result;
}

public static String[] getPOST_Data() throws UnsupportedEncodingException{
	String url = null, param;
	StringBuffer params = new StringBuffer();
	Enumeration enu = req.getParameterNames();
	int total = 0;

	while (enu.hasMoreElements()) {
		String paramName = (String)enu.nextElement();
		if(paramName.equals("url")){
			url = req.getParameter(paramName);
		}else{
			String pair = URLEncoder.encode(req.getParameter(paramName), "UTF-8");
			//String pair = req.getParameter(paramName);
			
			if(total == 0)params.append(paramName).append("=").append(pair);
			else params.append("&").append(paramName).append("=").append(pair);
			
			System.out.println("paramName:" + paramName + "/" + req.getParameter(paramName)); 
			++total;
		}
	}
	param = params.toString();

	String [] arr = {url, param};
	return arr;
}
%>

http://www.jiucool.com/java-sending-http-requests-get-and-post-method-request/
Java 发送 http 请求 (get 与 post 方法请求),以下代码经本人亲自调试可用!可以直接使用之。注意:通过 BufferedReader 读取远程返回的数据时,必须设置读取编码,否则中文会乱码!

package com.jiucool.www.struts.action;
 
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
 
public class post_request {
	public static final String GET_URL = "http://www.jiucool.com/request.php?key=j0r56u2";
 
    public static final String POST_URL = "http://www.jiucool.com/request.php";
    public static void readContentFromGet() throws IOException{
        // 拼凑get请求的URL字串,使用URLEncoder.encode对特殊和不可见字符进行编码
        String getURL = GET_URL + "&activatecode=" + URLEncoder.encode("久酷博客", "utf-8");
        URL getUrl = new URL(getURL);
        // 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,
        // 返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection
        HttpURLConnection connection = (HttpURLConnection) getUrl
                .openConnection();
        // 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到
        // 服务器
        connection.connect();
        // 取得输入流,并使用Reader读取
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));//设置编码,否则中文乱码
        System.out.println("=============================");
        System.out.println("Contents of get request");
        System.out.println("=============================");
        String lines;
        while ((lines = reader.readLine()) != null){
        	//lines = new String(lines.getBytes(), "utf-8");
            System.out.println(lines);
        }
        reader.close();
        // 断开连接
        connection.disconnect();
        System.out.println("=============================");
        System.out.println("Contents of get request ends");
        System.out.println("=============================");
    }
	public static void readContentFromPost() throws IOException{
        // Post请求的url,与get不同的是不需要带参数
        URL postUrl = new URL(POST_URL);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) postUrl
                .openConnection();
        // Output to the connection. Default is
        // false, set to true because post
        // method must write something to the
        // connection
        // 设置是否向connection输出,因为这个是post请求,参数要放在
        // http正文内,因此需要设为true
        connection.setDoOutput(true);
        // Read from the connection. Default is true.
        connection.setDoInput(true);
        // Set the post method. Default is GET
        connection.setRequestMethod("POST");
        // Post cannot use caches
        // Post 请求不能使用缓存
        connection.setUseCaches(false);
        // This method takes effects to
        // every instances of this class.
        // URLConnection.setFollowRedirects是static函数,作用于所有的URLConnection对象。
        // connection.setFollowRedirects(true);
 
        // This methods only
        // takes effacts to this
        // instance.
        // URLConnection.setInstanceFollowRedirects是成员函数,仅作用于当前函数
        connection.setInstanceFollowRedirects(true);
        // Set the content type to urlencoded,
        // because we will write
        // some URL-encoded content to the
        // connection. Settings above must be set before connect!
        // 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的
        // 意思是正文是urlencoded编码过的form参数,下面我们可以看到我们对正文内容使用URLEncoder.encode
        // 进行编码
        connection.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        // 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,
        // 要注意的是connection.getOutputStream会隐含的进行connect。
        connection.connect();
        DataOutputStream out = new DataOutputStream(connection
                .getOutputStream());
        // The URL-encoded contend
        // 正文,正文内容其实跟get的URL中'?'后的参数字符串一致
        String content = "key=j0r53nmbbd78x7m1pqml06u2&type=1&toemail=jiucool@gmail.com" + "&activatecode=" + URLEncoder.encode("久酷博客", "utf-8");
        // DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写道流里面
        out.writeBytes(content); 
        out.flush();
        out.close(); // flush and close
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));//设置编码,否则中文乱码
        String line="";
        System.out.println("=============================");
        System.out.println("Contents of post request");
        System.out.println("=============================");
        while ((line = reader.readLine()) != null){
            //line = new String(line.getBytes(), "utf-8");
            System.out.println(line);
        }
        System.out.println("=============================");
        System.out.println("Contents of post request ends");
        System.out.println("=============================");
        reader.close();
        connection.disconnect();
    }
}
HttpURLConnection.connect函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection.getInputStream()这个函数里面才正式发送出去。
在readContentFromPost() 中,顺序是重中之重,对connection对象的一切配置(那一堆set函数)都必须要在connect()函数执行之前完成。而对 outputStream的写操作,又必须要在inputStream的读操作之前。这些顺序实际上是由http请求的格式决定的。
http 请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content,在connect()函数里面,会根据HttpURLConnection对象的配置值生成http头,因此在调用connect函数之前,就必须把所有的配置准备好。
紧接着http头的是http请求的正文,正文的内容通过outputStream写入,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是在流关闭后,根据输入的内容生成http正文。
至此,http请求的东西已经准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入 outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。

2014.4-30:这是 IP 库的第二个公开版本,这个版本放开了国内市一级的数据。个人感觉更为实用,下载:http://bbs.ajaxjs.com/forum.php?mod=viewthread&tid=3703

感谢高春辉大大提供资源:)http://tool.17mon.cn/ipdb.html
原版是 Java 文件的,要转换为 JSP 形式的也容易,改一下字符串控制方法就可以了。源码如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@page import="java.io.*" %>
<%@page import="java.util.*" %>
<%@page import="java.net.*" %>
<%@page import="java.nio.*" %>
<%@ page trimDirectiveWhitespaces="true" %>
<%
class IPDataHandler {
	private String IP_DATA_PATH = "C:/project/wlsc/mmc/17monipdb.dat";
	private DataInputStream inputStream = null;
	private long fileLength = -1;
	private int dataLength = -1;
	private Map<String, String> cacheMap = null;
	private byte[] allData = null;
	public IPDataHandler(){
           prefix = prefix.replace("ipLocation.jsp", "17monipdb.dat");
           File file = new File(prefix);
		try {
			inputStream = new DataInputStream(new FileInputStream(file));
			fileLength = file.length();
			cacheMap = new HashMap<String, String>();
			if (fileLength >Integer.MAX_VALUE) {
				throw new Exception("the filelength over 2GB");
			}
			
			dataLength = (int) fileLength;
			allData = new byte[dataLength];
			inputStream.read(allData, 0, dataLength);
			dataLength = (int)getbytesTolong(allData, 0, 4,ByteOrder.BIG_ENDIAN);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	private long getbytesTolong(byte[] bytes, int offerSet,int size,ByteOrder byteOrder){
		if ((offerSet+size) > bytes.length || size <= 0) {
			return -1;
		}
		byte[] b = new byte[size];
		for (int i = 0; i < b.length; i++) {
			b[i] = bytes[offerSet+i];
		}
		
		ByteBuffer byteBuffer = ByteBuffer.wrap(b);
		byteBuffer.order(byteOrder);
		
		long temp = -1;
		if (byteBuffer.hasRemaining()) {
			temp = byteBuffer.getInt();
		}
		return temp;
	}
	
	private long ip2long(String ip) throws UnknownHostException {
		InetAddress address = InetAddress.getByName(ip);
		byte[] bytes = address.getAddress();	
		long reslut = getbytesTolong(bytes, 0, 4,ByteOrder.BIG_ENDIAN);
		return reslut;
	}
	

	private int getIntByBytes(byte[] b,int offSet)
	{
		if (b == null || (b.length < (offSet+3))) {
			return -1;
		}
		
		byte[] bytes = Arrays.copyOfRange(allData, offSet, offSet+3);
		byte[] bs = new byte[4];
		bs[3] = 0;
		for (int i = 0; i < 3;i++) {
			bs[i]=bytes[i];
		}
		
		return (int)getbytesTolong(bs, 0, 4, ByteOrder.LITTLE_ENDIAN);
	}

	
	public String findGeography(String address){
		if (address == null) {
			return "illegal address";
		}
		
		if (dataLength < 4 || allData == null) {
			return "illegal ip data";
		}
		
		String ip = "127.0.0.1";
		try {
			ip = Inet4Address.getByName(address).getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} 
		
		// String[] ipArray = StringUtils.split(ip, ".");
		 // String[] ipArray = ip.split(".");

		//String[] ipArray = {"8", "8", "8", "8"};
		String[] ipArray = ip.split("\\.");
		int ipHeadValue = Integer.parseInt(ipArray[0]);
		if (ipArray.length !=4 || ipHeadValue < 0 || ipHeadValue > 255) {
			return "illegal ip";
		}
		
		if (cacheMap.containsKey(ip)) {
			return cacheMap.get(ip);
		}
		
		
		long numIp = 1;
		try {
			numIp = ip2long(address);
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		}
		
		
		int tempOffSet = ipHeadValue* 4 + 4;
		long start = getbytesTolong(allData, tempOffSet, 4,ByteOrder.LITTLE_ENDIAN);
		int max_len = dataLength - 1028;
		long resultOffSet = 0;
		int resultSize = 0;
		
		for (start = start*8 + 1024; start < max_len; start+=8) {
			if (getbytesTolong(allData, (int)start+4, 4,ByteOrder.BIG_ENDIAN) >= numIp) {
				resultOffSet = getIntByBytes(allData, (int)(start+4+4));
				resultSize = (char)allData[(int)start+7+4];
				break;
			}
		}
		
		if (resultOffSet <= 0) {
			return "resultOffSet too small";
		}
		
		byte[] add = Arrays.copyOfRange(allData, (int)(dataLength+resultOffSet-1024), (int)(dataLength+resultOffSet-1024 + resultSize));
		try {
			if (add == null) {
				cacheMap.put(ip, new String("no data found!!"));
			} else {
				cacheMap.put(ip, new String(add,"UTF-8"));
			}
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		return cacheMap.get(ip);
	}
}
IPDataHandler obj = new IPDataHandler();

%>
<%=obj.findGeography("18.248.9.180")%>
获取 ip 并调用之:
// 获取请求 ip
	String ip = request.getHeader("x-forwarded-for");   
	if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
		ip = request.getHeader("Proxy-Client-IP");   

	if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) 
		ip = request.getHeader("WL-Proxy-Client-IP");   

	if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) 
		ip = request.getRemoteAddr();

	// 获取文件的绝对路径
	String adsoPath = request.getSession().getServletContext().getRealPath(request.getRequestURI()); 

	IPDataHandler obj = new IPDataHandler(adsoPath);
	//out.write(obj.findGeography("18.248.9.180"));
	out.write(obj.findGeography(ip));

Struts 2学习笔记 & 解决 EL 表达式不能调用方法、传参数的问题

初学入门推荐:《良葛格學習筆記》http://openhome.cc/Gossip/
Servlet 3.0 学习

JSP 部分

编辑web.xml文件,在里边添加如下内容:

<servlet>
        <servlet-name>Test</servlet-name>
        <servlet-class>com.nantian.jndi.Test</servlet-class>
        <init-param>
            <param-name>jndi</param-name>
            <param-value>java:comp/env/jdbc/test</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Test</servlet-name>
        <url-pattern>/Test</url-pattern>
    </servlet-mapping>
jsp 也可以接受 url mapping,

<servlet>
        <servlet-name>service</servlet-name>
        <jsp-file>/public/service.jsp</jsp-file>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>service</servlet-name>
        <url-pattern>/service/projectcase/*</url-pattern>
    </servlet-mapping>

注解方式 @WebServlet("/service/*")

J***A 语法部分

String.format("请求 URL 没有带有 %s 参数!", key);
IllegalArgumentException/NullPointerException
// 泛型的例子,调用
// bar obj = new bar<VideoInfo>();
// ArrayList<VideoInfo> list = obj.render(service, album.getId());
class bar<T>{
	public ArrayList<T> render(Service service, int albumId){
		AlbumInfoService videoList_Service = (AlbumInfoService)service.getServiceInCache();
		Map<String, Object> videoList = videoList_Service.findVideosByAlbum(albumId, 0 , 10).getVideos();
		ArrayList<T> list = (ArrayList<T>)videoList.get("results");

		return list;
		// Long totalCount = (Long)videoList.get("totalCount");
	}
}

/**
 * 获取任意的配置内容,读取某个节点的配置对象
 * 用法:<%=Config.getAnyConfig("companyInfo.name")%> 
 * @param key
 * @return
 */
public static String getAnyConfig(String node){
    return getAnyConfig(node, String.class);
}

/**
 *  Config.getConfigNode("companyInfo.name", String.class)
 *  ${viewController.companyInfo.name}
 * @param node
 * @param classType
 * @return
 */
@SuppressWarnings("unchecked")
public static <T> T getAnyConfig(String node, Class<T> classType){
    if(isLaunchByListener){
        if(!isConfig_Ready)
            throw new IllegalArgumentException("Application Level Error:未加载程序配置,请检查 Web.xml 是否已经添加 Listener");
        
        node = "bf.app_config." + node;
        System.out.println("正在获取节点:"+node);
        
        try {
            return (T)jsRuntime.eval(node);
        } catch (ScriptException e) {
            ajaxjs.Util.catchException(e, "读取配置%s失败!");
            return null;
        }
    }else{
        return (T)get(node, simpleConfig);
    }
}
泛型是没有数组的。编译器不承认 HashMap[]这种形式的
创建 MAP(匿名实例的写法)
Map map = new HashMap() {{
          put( "Name" , "Unmi" );
          put( "QQ" , "1125535" );
}};
遍历 MAP:
for(java.util.Map.Entry mapEntry : responseData.entrySet()) {
	Key key = mapEntry.getKey();  
	Value value = mapEntry.getValue();  
}

for (String key : cookie.keySet())
       cookieStr += key + "=" + cookie.get(key) + ";";

反射

需要包 java.lang.reflect.*
class Article extends BaseService<ArticleInfo>{
	public void f(){
		Class clazz=this.getClass();
		Method[] methods=clazz.getMethods();

		for(Method method:methods){
			if(method.getName().equals("findById")) {
				System.out.println("---");
			    System.out.print(method.getReturnType().getName()+" "+method.getName()+" ");
		        Class<?>[] types=method.getParameterTypes();

		        for(Class<?> type:types){
		    	    System.out.print(type.getName()+" ");
		        }

		        System.out.println();
		    }
		}
	}
}

Struts 部分

Webwork 到 2.0 版本的时候就是 Struts。现在公司的 WAP 项目在用,也终于让我有了学习的机会



学习的还是以模版语言为主。

基本流程语句:
<s:if test="%{false}">
    <div>Will Not Be Executed</div>
</s:if>
<s:elseif test="%{true}">
    <div>Will Be Executed</div>
</s:elseif>
<s:else>
    <div>Will Not Be Executed</div>
</s:else>
字符长度超出限定控制。如果超出 28 个,则自动截取,并显示 ……。

<p class="listDescription">
   <s:if test="description.length() > 28">
      <s:property value="description.substring(0, 28) + '……'" />
   </s:if>
   <s:else>
        <s:property value="description" />
   </s:else>
</p>
include 页面如何传参数?

<!--返回条-->
<s:set name="variable" value="'专辑'" />
<s:set name="variable2" value="'详情'" />
<%@ include file="public_new/returnBar.jsp" %>
<!--// 返回条-->
被引入的页面如下:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!--返回条-->
<div class="returnBar">
	<div class="goBackBtn" title="返回上一页" onclick="history.go(-1);"></div>
	<a href="." title="返回首页"><div class="homeBtn"></div></a>
	<s:property value="#variable" /><s:property value="#variable2" />
</div>
<!--// 返回条-->
工具篇:
Eclipse 可支持外部文件夹作为 src 源码:设置项目 Build Path--> Source-->Add Linked Folder 即可
如果 Eclipse 不显示 Build 文件夹下面的 Class 文件,可在 Project Exlopoer --》三角下拉菜单--》 CustomView... 取消打勾即可显示
如果某些类明明存在的,却不能成功 import 的话,可在 Build Path 将 JRE 删除再添加

Tomcat 可以快速热部署,设置 reload=true 即可。项目工程不要太大,否则会内存泄漏

大量 Java 教程资源(百度网盘)


内部教学课件及资料

 · 尚硅谷_教学课件_Java基础  · 尚硅谷_教学课件_SQL  · 尚硅谷_教学课件_oracle、sql、plsql  · 尚硅谷_教学课件_JDBC  · 尚硅谷_Java基础实战_Bank项目  · 尚硅谷_教学课件_JavaScript DOM编程  · 尚硅谷_教学课件_jQuery  · 尚硅谷_教学课件_Ajax  · 尚硅谷_教学课件_JavaWEB  · 尚硅谷_教学课件_Struts2  · 尚硅谷_教学课件_Hibernate4 开发入门相关

 · Java工程师必知必会_[尚硅谷].pdf  · JDK7的下载-安装-配置_[尚硅谷].pdf  · Oracle 安装视频及课件_[尚硅谷].rar  · Eclipse的安装配置与使用_[尚硅谷].pdf  · Eclipse常用设置_[尚硅谷].pdf  · Eclipse快捷键_[尚硅谷_宋红康].pdf  · 计算机常见编码_[尚硅谷].pdf  · Java常用英语汇总_[尚硅谷].pdf  · 云计算入门指南_[尚硅谷].pdf Java基础及数据库

 · 参悟Java基础核心技术_[尚硅谷_宋红康].pdf  · 深度解析Java内存原型_[尚硅谷_宋红康].pdf  · Java反射机制_[尚硅谷_宋红康].pdf  · Java反射机制的缺点_[尚硅谷_张晓飞].pdf  · Java 之23种设计模式解析_[尚硅谷_宋红康].pdf  · JDK中的设计模式应用实例_[尚硅谷_张晓飞].pdf  · 常用sql操作总结_[尚硅谷_宋红康].pdf  · Mysql 性能优化教程_[尚硅谷_张晓飞].pdf  · 4天贯通JDBC_[尚硅谷_宋红康].pdf  · 深入Java集合学习系列(一):HashMap的实现原理.pdf  · 深入Java集合学习系列(二):ArrayList实现原理.pdf  · 深入Java集合学习系列(三):ArrayList实现原理.pdf  · 深入Java集合学习系列(四):LinkedHashMap的实现原理.pdf 就业面试相关

 · 115个Java面试题和答案——终极(上).pdf  · 115个Java面试题和答案——终极(下).pdf  · plsql经典试题_[尚硅谷_宋红康].pdf  · sql面试题_ [尚硅谷_宋红康].pdf  · JavaWeb面试题_ [尚硅谷_张晓飞].pdf  · Java程序员的10道XML面试题_ [尚硅谷_宋红康].pdf  · Struts2面试题分析_[尚硅谷_佟刚].pdf  · Spring 面试题分析_[尚硅谷_佟刚].pdf  · Hibernate面试题分析_[尚硅谷_佟刚].pdf  · Android面试题大全_[尚硅谷_张晓飞].pdf JavaWeb及相关技术

 · JavaWeb知识结构图_[尚硅谷].jpg  · HTML培训教程_[尚硅谷_张晓飞].docx  · CSS培训教程_[尚硅谷_张晓飞].docx  · 核心Javascript培训教程_[尚硅谷_张晓飞].docx  · JavaScript DOM编程_[尚硅谷_张晓飞].docx  · jQuery培训教程_[尚硅谷_张晓飞].docx  · CSS扫盲_[尚硅谷_封捷].pdf  · HTML初步_[尚硅谷_封捷].pdf  · JavaScript学习笔记_[尚硅谷_封捷].pdf  · jQuery学习笔记_[尚硅谷_封捷].pdf  · HTTP协议简介_[尚硅谷_封捷].pdf  · Tomcat的设计模式分析_[尚硅谷_张晓飞].pdf  · Tomcat系统架构分析_[尚硅谷_张晓飞].pdf  · XML简介_[尚硅谷_封捷].pdf  · UML模型图_[尚硅谷_张晓飞].pdf  · Servlet_[尚硅谷_封捷].pdf  · 尚硅谷WEB书城_[尚硅谷_张晓飞].docx  · 正则表达式学习手册_[尚硅谷_张晓飞].pdf  · JNDI原理_ [尚硅谷_张晓飞].pdf  · ModelDriven和Preparable拦截器_[尚硅谷_封捷].pdf  · Web基础架构:负载均衡和LVS_[尚硅谷_张晓飞].pdf  · Web应用环境搭建_[尚硅谷_封捷].pdf  · 版本控制器[上]服务器端安装与配置_[尚硅谷_封捷].pdf  · 缓存技术浅谈_[尚硅谷_张晓飞].pdf JavaEE及相关技术

 · Mybatis_[尚硅谷_张晓飞].pdf  · Webservice_[尚硅谷_张晓飞].pdf  · JSR303验证_[尚硅谷_佟刚].pdf  · Spring IOC 容器中 Bean 的生命周期_[尚硅谷_佟刚].pdf  · Spring 整合 Struts2 详解_[尚硅谷_佟刚.pdf  · SpringMVC+运行流程解析_[尚硅谷_佟刚].pdf  · SpringSecurity之自定义用户权限信息的存取.pdf  · Struts2 运行流程分析_[尚硅谷_佟刚].pdf  · 扩展+Spring+Data+JPA_[尚硅谷_佟刚].pdf  · 使用 PowerDesigner_[尚硅谷_佟刚].pdf  · 图解Spring AOP_[尚硅谷_张晓飞].pdf  · 性能调优之Weblogic调优_[尚硅谷_张晓飞].pdf  · 性能调优之性能参数指标_[尚硅谷_张晓飞].pdf

Java基础必备

 ·JDK-7u71-windows-x64.exe[64位]  ·JDK-7u71-windows-i586.exe[32位]  ·Editplus.zip[文本编辑器] Eclipse 及其插件

 ·eclipse-jee-kepler-SR1-win32.zip[32位]  ·eclipse-jee-kepler-SR1-win64.zip[64位]  ·springsource-tool-suite-3.4.0.RELEASE.zip[spring插件]  ·hibernatetools-Update-4.1.1.zip[hibernate插件]  ·subclipse.zip[SVN插件]  ·eclipse-maven3-plugin.7z[Maven插件] Oracle

 ·oracle 10g.zip[安装包]  ·PL.SQL.Developer.v7.1.4.1390-Crack.zip[PL/SQL安装包]  ·10201_client_win32.zip[客户端安装包]  ·Toad for Oracle 12.rar[操作Oracle数据库的工具包] MySQL

 ·Mysql_win64.msi[64位]  ·Mysql_win32.msi[32位]  ·SQLyog-10.0.0-0.zip[客户端]  ·MySQL_Workbench_5_2_37_Jisuxz.com.rar[客户端] Tomcat

 ·Apache-tomcat-6.0.16.zip[Tomcat安装包]  ·Apache-tomcat-6.0.18-src.zip[Tomcat源码包] Android

 ·adt-bundle-windows-x86.zip[包含eclipse/sdk/adt的Android开发工具包]  ·SQLiteExpertPersSetup.exe[android中的Sqlite数据库客户端工具]  ·haxm-windows_r03.zip[模拟器的Intel硬件加速] 建模工具

 ·Rose[项目开发建模]  ·Staruml.zip[项目开发建模]   ·PowerDesigner15.1_CN_CR.rar[数据库建模] 其它

 ·思维导图MindManager2012破解版.zip  ·pache-james-2.3.2.zip[邮件服务器安装包]  ·apache-james-2.3.2-src.zip[邮件服务器源码包]  ·apache-ant-1.7.1-bin.zip[应用构建工具Ant安装包]  ·apache-ant-1.7.1-src.zip[应用构建工具Ant源码包]  ·apache-maven-3.0.4-bin.zip[应用管理工具Maven安装包] 

Javascript & jQuery &Ajax&JSON

 · jquery-1.7.2.js  · jquery-1.7.2.min.js  · jQuery插件  · EasyUI+v1.3.4官方API中文版  · EasyUI+v1.3.4官方API中文版.rar  · jackson-src-1.7.1.zip  · ext-3.0.0.zip  · google-gson-2.2.4-release.zip apache-commons框架

 · commons-validator-1.3.1-src.zip  · commons-lang3-3.2.1-src.zip  · commons-fileupload-1.2.1-src.zip  · commons-dbutils-1.3-bin.zip  · commons-pool-1.5.5-bin.zip  · commons-io-2.0-bin.zip  · commons-lang-2.5-src.zip  · commons-logging-1.1.1-bin.zip  · commons-io-2.0-src.zip  · commons-lang3-3.2.1-bin.zip  · commons-lang-2.5-bin.zip  · commons-dbutils-1.3-src.zip  · commons-pool-1.5.5-src.zip  · commons-validator-1.3.1.zip  · commons-logging-1.1.1-src.zip  · commons-dbcp-1.4-src.zip  · commons-fileupload-1.2.1-bin.zip  · commons-codec-1.4-bin.zip  · commons-dbcp-1.4-bin.zip  · commons-collections-3.2.1-src.zip  · commons-codec-1.4-src.zip  · commons-beanutils-1.8.0-bin.zip  · commons-beanutils-1.8.0-src.zip  · commons-collections-3.2.1-bin.zip SSH框架

 · struts-menu-2.4.3.zip  · spring-modules-0.9-with-dependencies.zip  · spring-framework-3.1.0.CI-1163-dependencies.zip  · spring-framework-2.5.6.SEC01-with-dependencies.zip  · struts-menu-2.4.3-src.zip  · struts-2.3.15.3-all.zip  · spring-framework-4.0.0.RELEASE-dist.zip  · struts-2.3.4-all.zip  · struts-1.3.8-all.zip  · spring-framework-3.1.1.RELEASE-with-docs.zip  · struts2-2.2.1-all.zip  · struts-2.1.8.1-all.zip  · hibernate-distribution-3.6.0.Final-dist.zip  · hibernate-distribution-3.5.1-Final-dist.zip  · hibernate-release-4.2.4.Final.zip spring-data-jpa(1.4.2.RELEASE)

 · spring-data-jpa-1.4.2.RELEASE-sources.jar  · spring-data-jpa-1.4.2.RELEASE-javadoc.jar  · spring-data-jpa-1.4.2.RELEASE.jar  · spring-data-jpa-reference.pdf spring-data-commons

 · spring-data-commons-1.6.2.RELEASE-sources.jar  · spring-data-commons-1.6.2.RELEASE.jar  · spring-data-commons-1.6.2.RELEASE-javadoc.jar shiro

 · shiro所有相关jar包  · shiro-root-1.2.2-source-release.zip spring-security

 · spring-security-3.1.0.M1.zip  · spring-security-2.0.5.zip 工作流

 · jbpm-4.3.zip  · jbpm-4.4.zip  · jbpm-jpdl-suite-3.2.3.zip  · activiti-5.15.1.zip android

 · activiti-5.15.1.zip  · adt-bundle-windows-x86-20140702.zip  · android-sdk-windows.zip 其它

 · spring-modules-0.9.zip  · poi-src-3.5-FINAL-20090928.zip  · poi-bin-3.5-FINAL-20090928.zip  · slf4j-1.6.1.zip  · pinyin4j-2.5.0.zip  · ognl.zip  · mysql-connector-java-5.1.7.zip  · joda-time-2.3-dist.zip  · jfreechart-1.0.13-javadocs.zip  · jfreechart-1.0.13.zip  · jdom-1.1.zip  · javamail-1_4_1.zip  · jakarta-taglibs-standard-1.1.2-src.zip  · jakarta-taglibs-standard-1.1.2.zip  · jaf-1_1_1.zip  · hibernate-validator-5.0.0.CR2-dist.zip  · guice-1.0-src.zip  · guice-1.0.zip  · displaytag-1.2-bin.zip  · displaytag-1.2-src.zip  · cewolf-1.1.4.zip  · cewolf-1.0-bin-src.zip  · c3p0-0.9.1.2.src.zip  · c3p0-0.9.1.2.bin.zip  · apache-log4j-1.2.15.zip  · xwork2-2.1.rar  · dom4j-1.6.1.rar  · elecfans.com-XPath.rar  · xwork-assembly-2.1.6-all.zip  · quartz-2.2.1-distribution.tar.gz  · xloadtree_zh_cn.zip  · xdoclet-src-1.2.3.zip  · xdoclet-bin-1.2.3.zip  · xfire-distribution-1.2.6.zip  · xdoclet-lib-1.2.3.zip

J2SE相关

 · 设计模式手册.chm  · jdk150.chm  · JDK7_docs.CHM  · J2SE6.0.chm JavaWEB相关

 · Java_EE_6_API.chm  · J2EE1.5.chm  · Ajax帮助文档.chm  · XMLHTTP 手册.Chm  · XML指南.chm  · CSS2.0_DOC.chm  · CSS_精通CSS滤镜.chm  · CSS_5日精通CSS层叠样.chm  · 样式表中文手册.chm  · 网页设计本色常识.chm  · servlet.chm  · JSP语法.chm  · j2ee-HttpServlet.chm  · html̳.chm  · DHTML文档对象.CHM  · DHTML手册(英文).chm  · css样式表滤镜.chm  · CSS样式表.CHM  · css2gb.chm  · css2.chm  · CSSFilter2.0_DOC_CN.chm  · jQuery.chm  · jdom.chm  · DHTML_DOC_CN.chm  · 网页***完全手册.chm  · XDoclet1.2.chm  · Tomcat_Servlet&Jsp_API文档.chm  · JScript 中文参考手册.chm  · JspSmartUpload.chm 数据库相关

 · MySQL.chm  · PostgreSQL8.1_DOC_CN.chm  · ORACLE_10g帮助文档(下载).zip  · ORACLE 九阴真经.chm  · MySQL_5.1_zh.chm  · 数据库技术:《SQL 参考手册》中文版.chm 框架相关

 · Hibernate3.1_DOC_CN.chm  · StrutsAPI 1.2.chm  · Validato_表单验证.chm  · spring3.1.chm  · Struts1.3.chm  · Spring-Reference_zh_CN.chm  · Spring+Security教程.chm  · Spring2.0_DOC_CN.chm  · Hibernate3.2.chm  · hibernate 帮助文档.chm  · jbpm3.chm  · JBPM用户手册.chm  · Struts2.chm 其它

 · Comm2.0.chm  · WebServices.chm  · 英语资料大全.chm  · VBScript_DOC.chm  · J2ME2.5.chm  · DOS实例手册.chm  · jFreeChart.CHM  · Ant1.7.chm  · Log4j1.2.chm  · JUnit4.1.chm

解决 EL & 表达式不能调用方法、传参数的问题

在自定义标签的使用中,EL 表达式是必不可少的一环。官方的 API 需要到了最新版本(EL v2.2, JDK7、Tomcat 7)才可以提供调用方法的直接方式。在老版本的 Tomcat 下,如何才可以像 Strus 那样调用方法呢?国外一位开发者给出了答案。首先复制以下两个类 ELMethod.java 和 Call.java 到你的项目中(适当修改包名)。
http://www.vineetmanohar.com/2010/07/how-to-pass-parameters-in-el-methods/

http://www.vineetmanohar.com/2010/08/calling-static-methods-from-el/

ELMethod.java:

package com.vineetmanohar.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Extend this class to implement a server side method that takes arguments that
 * you would like to call via expression language.
 * 
 * @author Vineet Manohar
 */
public abstract class ELMethod extends HashMap<Object, Object> {
	private static final long serialVersionUID = 1L;

	private final int numArgs;

	/**
	 * @param numArgs
	 *            number of arguments this method takes
	 */
	protected ELMethod(int numArgs) {
		this.numArgs = numArgs;
	}

	@Override
	public Object get(Object key) {
		// if exactly one argument, call the result() method
		if (numArgs == 1) {
			return result(new Object[] {key});
		}

		// if more tha one argument
		return new Arg(this, key);
	}

	public int getNumArgs() {
		return numArgs;
	}

	/**
	 * 1) Implement this method in the child class. This method becomes
	 * accesible via expression language.
	 * 
	 * 2) Call this method using map syntax, by treating the instance of the
	 * child class as a map of map of maps...
	 * 
	 * For example, you could extends this class and create a class called
	 * FormatDate. In that class, the result method would expect 2 arguments,
	 * format string and date object.
	 * 
	 * ${FormatDate["MMM dd"][user.creationDate]}, where dateFormat is an
	 * instance of the child class.
	 * 
	 * @param args
	 * @return
	 */
	public abstract Object result(Object[] args);
	
	public static class Arg extends HashMap<Object, Object> {
		private static final long serialVersionUID = 1L;
		private List<Object> args = new ArrayList<Object>();
		private ELMethod parent;

		public Arg(ELMethod eLMethod, Object key) {
			this.parent = eLMethod;
			this.args.add(key);
		}

		@Override
		public Object get(Object key) {
			this.args.add(key);

			// if all the arguments have been received, invoke the result method
			if (args.size() == parent.getNumArgs()) {
				Object retVal = parent.result(args.toArray());

				return retVal;
			}

			return this;
		}
	}
}
Call.java:

package com.vineetmanohar.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class lets you call static methods from EL
 * 
 * Step 1) Create an instance of this class and bind it to the "call" variable
 * in your EL. For example, in a JSP do the following:
 * request.setAttribute("call", new Call());
 * 
 * Step 2) Call any static method as follows:
 * 
 * ${call["some.package.SomeClass.methodName"]["arg1"][arg2]}
 * 
 * The first argument is the fully qualified class and method name. The
 * remaining arguments are arguments to the method that you are calling.
 * 
 * Note: method overloading not supported
 * 
 * Note: method must be static
 * 
 * @author Vineet Manohar
 */
public class Call extends HashMap<String, Object> {
	private static final long serialVersionUID = 1L;

	@Override
	public Object get(Object key) {
		String fullyQualifiedMethodName = (String) key;

		// format of key is package.Class.method
		Pattern pattern = Pattern.compile("(.+)\\.([^\\.]+)");
		Matcher m = pattern.matcher(fullyQualifiedMethodName);
		if (m.matches()) {
			String fqClassName = m.group(1);
			String methodName = m.group(2);
			Class<Object> clazz;
			try {
				clazz = (Class<Object>) Class.forName(fqClassName);
			} catch (ClassNotFoundException e) {
				throw new IllegalArgumentException("Invalid method name: "
						+ key, e);
			}
			Method[] methods = clazz.getMethods();
			for (final Method method : methods) {
				if ((method.getModifiers() & Modifier.STATIC) == 0) {
					continue;
				}

				if (method.getName().equals(methodName)) {
					// return the first method found
					int numParameters = method.getParameterTypes().length;

					if (numParameters == 0) {
						return invokeMethod(method);
					}

					return new ELMethod(numParameters) {
						@Override
						public Object result(Object[] args) {
							return invokeMethod(method, args);
						}
					};
				}
			}
		}

		throw new IllegalArgumentException("Invalid method name: " + key
				+ ". Must be a fully qualified class and method name");
	}

	private Object invokeMethod(final Method method, Object... args) {
		try {
			return method.invoke(null, args);
		} catch (IllegalArgumentException e) {
			throw new RuntimeException("Exception while executing method", e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException("Exception while executing method", e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException("Exception while executing method", e);
		}
	}
}
然后实例化 Call 对象。反正在 JSP 里随你喜欢即可,如 request.setAttribute("call", new Call()); 或 <jsp:useBean id="call" class="Call" scope="application" /> 都冇问题。
最后一步就是解决问题的目标,调用方法并传参数了。试写出表达式:${call["com.mycompany.util.DateUtils.formatDate"]["MMM, dd"][account.creationDate]},其中 com.mycompany.util.DateUtils.formatDate 是 Java 静态方法,要写全称。最后两项是传入的参数,分别可以是字符串和当然 EL 对象(如account.creationDate)。
观其上述源码,实际是利用了 Java 反射的原理调用方法。不要注意一点的是,不支持方法的重载哦(Overloaded)。
如果不是静态方法,实例方法可不可以调用呢?按照作者的介绍也是可以的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: