- 浏览: 58077 次
- 性别:
- 来自: 杭州
最新评论
-
bibithink:
LinkedHashMap 的内部实现是 一个哈希表 + 双向 ...
基于LinkedHashMap实现LRU缓存调度算法原理及应用 -
javaboy2010:
不错,还没毕业,写出如此代码,楼主很强啊! 向楼主学习!
自己编写一个基于Velocity的MVC框架 -
lwclover:
lz的代码在多线程环境下 会出问题
基于LinkedHashMap实现LRU缓存调度算法原理及应用 -
woming66:
condeywadl 写道观爷我来顶一个 哈哈
哈哈 你来晚 ...
基于LinkedHashMap实现LRU缓存调度算法原理及应用 -
condeywadl:
观爷我来顶一个 哈哈
基于LinkedHashMap实现LRU缓存调度算法原理及应用
公司留了作业(还有一个月毕业),让预习Velocity,在家呆着没意思,反正闲着也是闲着,看了VelocityViewServlet源码,感觉还可以,取其精华去其糟粕,自己写了一个基于Velocity的MVC框架,废话不多说了,直接进入正题。
VelocityActionServlet是整个MVC框架的核心类,拦截所有的Action请求,分发给不同的Action进行处理。
init()方法初始化了系统需要的资源和VelocityEngine。
doProcess()是这个类的核心方法,处理用户请求,获取context数据,获取模板,合成html
这是一个简单的Bean工程实现,加载类路径下的beans.properties文件(这里完全可以用xml,这都是次要的问题,不是核心问题,等以后有时间了可以继续改进)
beans.properties文件,
路径=Action类,如:
/user=com.velocity.test.action.UserAction
ObjectPool对象池的实现,主要是对Writer进行管理。
VelocityWriter类对Writer进行修饰,加入了Buffer。
ServletActionContext这个类,挺简单的,一看就能明白,和Struts2的ServletActionContext功能一样。
这个更不用说了,玩过Struts2的人一看就知道。
一个接口,所有的Action类都必须要实现这个接口。
最后就是这个web.xml
核心的东西就是这些,下面玩一下这个框架。
1、定义Action类
2、在beans.properties加入
/user=com.velocity.test.action.UserAction
3、定义模板,放到WebRoot/vm/下(这个路径可以在web.xml中配)
4、访问http://localhost:8080/Veloctiy/user.html 一看就知道
总之:这个就是现在闲着没意思编着玩的,缺少很多功能(如上传,参数类型装换,还有对整个框架的扩展如插件化等等),跟成型的MVC Framework没法发,但是如果有人力、时间、金钱,相信我们国人也会编出相当完美优雅的框架。
还有一个月就毕业了,回望过去,还是很向往自己的大学生活,面对现实只能勇敢的去面对。
VelocityActionServlet是整个MVC框架的核心类,拦截所有的Action请求,分发给不同的Action进行处理。
init()方法初始化了系统需要的资源和VelocityEngine。
doProcess()是这个类的核心方法,处理用户请求,获取context数据,获取模板,合成html
package com.zzq.velocity.core; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.lang.reflect.Method; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.collections.ExtendedProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.io.VelocityWriter; public class VelocityActionServlet extends HttpServlet { private static Log log = LogFactory.getLog(VelocityActionServlet.class); /** * request放入VelocityContext中的key */ public static final String REQUEST = "request"; /** * response放入VelocityContext中的key */ public static final String RESPONSE = "response"; public static final String CONTENT_TYPE = "default.contentType"; public static final String OUTPUT_ENCODING = "output.encoding"; /** * 默认的输出编码 */ public static final String DEFAULT_OUTPUT_ENCODING = "UTF-8"; /** * velocity.properties在web.xml文件默认的key */ protected static final String INIT_PROPS_KEY = "org.apache.velocity.properties"; /** * velocity.properties在默认的路径 */ protected static final String DEFAULT_PROPERTIES_PATH = "/WEB-INF/velocity.properties"; /** * 默认的ContextType */ public static final String DEFAULT_CONTENT_TYPE = "text/html"; /** * 对输出流维护的池 */ private ObjectPool<VelocityWriter> pool = new ObjectPool<VelocityWriter>(40); private VelocityEngine velocity = null; /** * 例如user.do?method=add -> 会调用UserAction的add方法 相当于DispatchAction功能 */ private static final String DEFAULT_PARAMETER_METHOD = "method"; private static final String INIT_PARAMETER_KEY = "parameter"; private String parameterMethod; /** * 最终默认的ContentType */ private String defaultContentType; private static final String INIT_TEMPLATEPATH_KEY = "templatePath"; private static final String FILE_RESOURCE_LOADER_PATH = "file.resource.loader.path"; public void init(ServletConfig config) throws ServletException { super.init(config); /** * 初始化Velocity引擎 */ initVelocity(config); defaultContentType = (String)getVelocityProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); String encoding = (String)getVelocityProperty(OUTPUT_ENCODING, DEFAULT_OUTPUT_ENCODING); parameterMethod = findInitParameter(config, INIT_PARAMETER_KEY, DEFAULT_PARAMETER_METHOD); int index = defaultContentType.lastIndexOf(";"); if(index < 0) { defaultContentType += "; charset=" + encoding; } } /** * 初始化Velocity引擎 * @param config * @throws ServletException */ protected void initVelocity(ServletConfig config) throws ServletException { try { velocity = new VelocityEngine(); ExtendedProperties p = loadConfiguration(config); String templatePath = findInitParameter(config, INIT_TEMPLATEPATH_KEY); templatePath = config.getServletContext().getRealPath("/") + templatePath; velocity.setProperty(FILE_RESOURCE_LOADER_PATH, templatePath); velocity.setExtendedProperties(p); velocity.init(); } catch (Exception e) { log.error("初始化velocity引擎时出错!"); throw new ServletException(e); } } protected String getVelocityProperty(String key, String defaultValue) { String value = (String)velocity.getProperty(key); if(null == value || "".equals(value.trim())) { value = defaultValue; } return value; } /** * 加载velocity.properties配置文件 */ protected ExtendedProperties loadConfiguration(ServletConfig config) { String propsFile = findInitParameter(config, INIT_PROPS_KEY); if(null == propsFile) { propsFile = DEFAULT_PROPERTIES_PATH; } ExtendedProperties properties = new ExtendedProperties(); InputStream inputStream = getServletContext().getResourceAsStream(propsFile); try { inputStream = getServletContext().getResourceAsStream(propsFile); if(null != inputStream) { properties.load(inputStream); } } catch (IOException e) { throw new RuntimeException(e); } finally { if(null != inputStream) { try { inputStream.close(); } catch (IOException e) { throw new RuntimeException("关闭" + propsFile + "文件时出现异常!"); } } } return properties; } protected String findInitParameter(ServletConfig config, String key) { String value = config.getInitParameter(key); if(null == value || "".equals(value.trim())) { value = config.getServletContext().getInitParameter(key); } return value; } protected String findInitParameter(ServletConfig config, String key, String defaultValue) { String value = config.getInitParameter(key); if(null == value || "".equals(value.trim())) { value = config.getServletContext().getInitParameter(key); } if(null == value || "".equals(value.trim())) { value = defaultValue; } return value; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doProcess(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doProcess(request, response); } /** * 请求处理的核心方法 * @param request * @param response */ protected void doProcess(HttpServletRequest request, HttpServletResponse response) { Context context = null; try { initServletActionContext(request, response); initActionContext(request); setContentType(request, response); Action action = getAction(request); String templateName = doExecute(action, request, response); //在Action中调用response.sendRedirect(); if(null == templateName) { return ; } context = createContext(action, request, response); Template template = handleRequest(templateName, request, response, context); mergeTemplate(template, context, response); } catch(Exception e) { try { e.printStackTrace(response.getWriter()); response.getWriter().flush(); } catch (IOException e1) { throw new RuntimeException(e); } } finally { destoryServletActionContext(); destoryActionContext(request); } } /** * 给ServletActionContext赋值 * @param request * @param response */ protected void initServletActionContext(HttpServletRequest request, HttpServletResponse response) { ServletActionContext.setRequest(request); ServletActionContext.setResponse(response); } /** * 给ActionContext赋值 * @param request */ protected void initActionContext(HttpServletRequest request) { //处理request Map<String, Object> values = new HashMap<String, Object>(); Enumeration enumeration = request.getAttributeNames(); while(enumeration.hasMoreElements()) { String key = (String)enumeration.nextElement(); values.put(key, request.getAttribute(key)); } ActionContext.setRequest(values); //处理session values = new HashMap<String, Object>(); HttpSession session = request.getSession(); if(null != session) { session = request.getSession(true); } enumeration = session.getAttributeNames(); while(enumeration.hasMoreElements()) { String key = (String)enumeration.nextElement(); values.put(key, session.getAttribute(key)); } ActionContext.setSession(values); //处理ServletContext values = new HashMap<String, Object>(); ServletContext servletContext = session.getServletContext(); enumeration = servletContext.getAttributeNames(); while(enumeration.hasMoreElements()) { String key = (String)enumeration.nextElement(); values.put(key, session.getAttribute(key)); } ActionContext.setServletContext(values); } /** * 销毁当前线程的ServletActionContext */ protected void destoryServletActionContext() { ServletActionContext.destory(); } /** * 销毁当前线程的ActionContext * @param request */ protected void destoryActionContext(HttpServletRequest request) { Map<String, Object> values = ActionContext.getContext().getRequest(); for(Iterator<String> iter = values.keySet().iterator(); iter.hasNext(); ) { String key = iter.next(); request.setAttribute(key, values.get(key)); } values = ActionContext.getContext().getSession(); HttpSession session = request.getSession(); for(Iterator<String> iter = values.keySet().iterator(); iter.hasNext(); ) { String key = iter.next(); session.setAttribute(key, values.get(key)); } values = ActionContext.getContext().getServletContext(); ServletContext servletContext = session.getServletContext(); for(Iterator<String> iter = values.keySet().iterator(); iter.hasNext(); ) { String key = iter.next(); servletContext.setAttribute(key, values.get(key)); } ActionContext.destory(); } protected String doExecute(Action action, HttpServletRequest request, HttpServletResponse response) throws Exception { String methodName = request.getParameter(parameterMethod); if(null == methodName || "".equals(methodName.trim())) { methodName = "execute"; } Method method = action.getClass().getMethod(methodName); String templateName = (String)method.invoke(action); return templateName; } protected Context createContext(Action action, HttpServletRequest request, HttpServletResponse response){ VelocityContext context = new VelocityContext(); context.put(REQUEST, request); context.put(RESPONSE, response); Map<String, Object> params = action.getContext(); for(Iterator<String> iter = params.keySet().iterator(); iter.hasNext(); ) { String key = iter.next(); Object value = params.get(key); context.put(key, value); } return context; } private Action getAction(HttpServletRequest request) { String requestURI = request.getRequestURI(); String actionName = requestURI.substring(requestURI.indexOf('/', 1), requestURI.lastIndexOf('.')); Action action = (Action)BeanFactory.getBean(actionName); if(null == action) { throw new RuntimeException("没有找到路径为:" + actionName + "对应的Action"); } return action; } protected void setContentType(HttpServletRequest request, HttpServletResponse response) { response.setContentType(defaultContentType); } protected Template handleRequest(String templateName, HttpServletRequest request, HttpServletResponse response, Context ctx) { //do something...... Template template = null; try { template = velocity.getTemplate(templateName); } catch (Exception e) { throw new RuntimeException(e); } return template; } protected void mergeTemplate(Template template, Context context,HttpServletResponse response) throws UnsupportedEncodingException, IOException { VelocityWriter vw = null; Writer writer = getResponseWriter(response); try { vw = pool.get(); if(null == vw) { vw = new VelocityWriter(writer, 4*1024, true); } else { vw.recycle(writer); } template.merge(context, writer); } finally { if(null != vw) { vw.flush(); vw.recycle(null); pool.put(vw); } } } protected Writer getResponseWriter(HttpServletResponse response) throws UnsupportedEncodingException, IOException { Writer writer = null; try { writer = response.getWriter(); } catch (IllegalStateException e) { String encoding = response.getCharacterEncoding(); if (encoding == null) { encoding = DEFAULT_OUTPUT_ENCODING; } writer = new OutputStreamWriter(response.getOutputStream(), encoding); } return writer; } }
这是一个简单的Bean工程实现,加载类路径下的beans.properties文件(这里完全可以用xml,这都是次要的问题,不是核心问题,等以后有时间了可以继续改进)
beans.properties文件,
路径=Action类,如:
/user=com.velocity.test.action.UserAction
package com.zzq.velocity.core; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; public class BeanFactory { private static Map<String, String> map = new HashMap<String, String>(); static { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("beans.properties"); try { Properties prop = new Properties(); prop.load(is); Iterator iter = prop.keySet().iterator(); while(iter.hasNext()) { String key = (String)iter.next(); String className = prop.getProperty(key); map.put(key, className); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("初始化BeanFactory失败", e); } finally { try { if(null != is) { is.close(); } } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } } } public static Object getBean(String id) { //prototype String className = map.get(id); if(null == className) { return null; } Object action = null; try { action = Class.forName(className).newInstance(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("创建Action类:" + className + "失败", e); } return action; } }
ObjectPool对象池的实现,主要是对Writer进行管理。
package com.zzq.velocity.core; import java.util.ArrayList; import java.util.List; /** * 对象池 * @author zzq * */ public class ObjectPool<T> { /** * 默认池大小 */ public static final int DEFAULT_POOL_SIZE = 10; private int max; private int current=-1; private List<T> pool = null; public ObjectPool() { this(DEFAULT_POOL_SIZE); } public ObjectPool(int size) { max = size; pool = new ArrayList<T>(size); } public T get() { T obj = null; synchronized (this) { if(current > -1) { obj = pool.get(current); current --; } } return obj; } public void put(T obj) { synchronized (this) { current ++; if(current < max) { pool.add(obj); return ; } current --; } } public int getMax() { return max; } public List<T> getPool() { return pool; } }
VelocityWriter类对Writer进行修饰,加入了Buffer。
package com.zzq.velocity.core; import java.io.IOException; import java.io.Writer; public class VelocityWriter extends Writer { private int bufferSize; private boolean autoFlush; private Writer writer; private char cb[]; private int next; private static final int DEFAULT_CHARBUFFER_SIZE = 8 * 1024; public VelocityWriter(Writer writer) { this(writer, DEFAULT_CHARBUFFER_SIZE, true); } public VelocityWriter(Writer writer, int size, boolean isFlush) { if(size < 0) { throw new IllegalArgumentException("Buffer size < 0"); } this.bufferSize = size; this.autoFlush = isFlush; this.writer = writer; cb = size > 0 ? new char[size] : null; next = 0; } public int getBufferSize() { return bufferSize; } public boolean isAutoFlush() { return autoFlush; } private final void flushBuffer() throws IOException { if(bufferSize == 0) { return ; } if(next == 0) { return ; } writer.write(cb, 0, next); this.next = 0; } public final void clear() { next = 0; } private final void bufferOverflow() throws IOException { throw new IOException("Buffer over flow!"); } public final void write(int c) throws IOException { if(bufferSize == 0) { writer.write(c); return ; } if(next >= bufferSize) { if(autoFlush) { flushBuffer(); } else { bufferOverflow(); } } cb[next++] = (char)c; } public final void write(char buf[]) throws IOException { write(buf, 0, buf.length); } public final void write(String s, int off, int len) throws IOException { write(s.toCharArray(), off, len); } public final void write(String s) throws IOException { write(s, 0, s.length()); } @Override public void write(char[] cbuf, int off, int len) throws IOException { if(bufferSize == 0) { writer.write(cbuf, off, len); return ; } if (len == 0) { return; } if (len >= bufferSize) { if (autoFlush) flushBuffer(); else bufferOverflow(); writer.write(cbuf, off, len); return; } if(len + off > cbuf.length) { throw new IllegalArgumentException("len + off > cbuf.length"); } while(len > 0) { int b = len > bufferSize - next ? bufferSize - next : len; System.arraycopy(cb, next, cbuf, off, b); next += b; if(next >= bufferSize) { if(autoFlush) { flushBuffer(); } else { bufferOverflow(); } } off += b; len -= b; } } public final void recycle(Writer writer) { this.writer = writer; clear(); } @Override public void close() throws IOException { if(writer != null) { flush(); writer.close(); } } @Override public void flush() throws IOException { flushBuffer(); writer.flush(); } }
ServletActionContext这个类,挺简单的,一看就能明白,和Struts2的ServletActionContext功能一样。
package com.zzq.velocity.core; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class ServletActionContext { private static ThreadLocal<HttpServletRequest> reqContext = new ThreadLocal<HttpServletRequest>(); private static ThreadLocal<HttpServletResponse> respContext = new ThreadLocal<HttpServletResponse>(); public static void setRequest(HttpServletRequest request) { reqContext.set(request); } public static void setResponse(HttpServletResponse response) { respContext.set(response); } public static HttpServletRequest getRequset() { return reqContext.get(); } public static HttpServletResponse getResponse() { return respContext.get(); } public static HttpSession getSession() { return reqContext.get().getSession(); } public static ServletContext getServletContext() { return reqContext.get().getSession().getServletContext(); } public static void destory() { reqContext.remove(); respContext.remove(); } }
这个更不用说了,玩过Struts2的人一看就知道。
package com.zzq.velocity.core; import java.util.Map; /** * 将Servlet API 进行解耦 * @author zzq * */ public class ActionContext { private static ActionContext instance = new ActionContext(); private static ThreadLocal<Map<String, Object>> request = new ThreadLocal<Map<String, Object>>(); private static ThreadLocal<Map<String, Object>> session = new ThreadLocal<Map<String, Object>>(); private static ThreadLocal<Map<String, Object>> servletContext = new ThreadLocal<Map<String, Object>>(); private ActionContext() {} public static ActionContext getContext() { return instance; } public static void setRequest(Map<String, Object> value) { request.set(value); } public static void setSession(Map<String, Object> value) { session.set(value); } public static void setServletContext(Map<String, Object> value) { servletContext.set(value); } public Map<String, Object> getSession() { return session.get(); } public Map<String, Object> getServletContext() { return servletContext.get(); } public Map<String, Object> getRequest() { return request.get(); } public static void destory() { request.remove(); session.remove(); servletContext.remove(); } }
一个接口,所有的Action类都必须要实现这个接口。
package com.zzq.velocity.core; import java.util.Map; public interface Action { public String execute() throws Exception; /** * 获取Velocity需要的Context数据 * @return Context */ public Map<String, Object> getContext(); }
最后就是这个web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>VelocityActionServlet</servlet-name> <servlet-class>com.zzq.velocity.core.VelocityActionServlet</servlet-class> <init-param> <param-name>properties</param-name> <param-value>/WEB-INF/velocity.properties</param-value> </init-param> <init-param> <param-name>templatePath</param-name> <param-value>/vm</param-value> </init-param> <load-on-startup>10</load-on-startup> </servlet> <servlet-mapping> <servlet-name>VelocityActionServlet</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> </web-app>
核心的东西就是这些,下面玩一下这个框架。
1、定义Action类
package com.velocity.test.action; import java.util.HashMap; import java.util.Map; import com.zzq.velocity.core.Action; import com.zzq.velocity.core.ServletActionContext; public class UserAction implements Action { private Map<String, Object> map = new HashMap<String, Object>(); public String execute() throws Exception { return "/login.vm"; } public String login() { String username = ServletActionContext.getRequset().getParameter("username"); String password = ServletActionContext.getRequset().getParameter("password"); User user = new User(); user.setUsername(username); user.setPassword(password); System.out.println(username); System.out.println(password); map.put("user", user); ServletActionContext.getSession().setAttribute("user", user); return "/login_success.vm"; } public String register() { String username = ServletActionContext.getRequset().getParameter("username"); String password = ServletActionContext.getRequset().getParameter("password"); System.out.println(username); System.out.println(password); return "/register_success.vm"; } public String registerInput() { return "/register.vm"; } public Map<String, Object> getContext() { return map; } }
2、在beans.properties加入
/user=com.velocity.test.action.UserAction
3、定义模板,放到WebRoot/vm/下(这个路径可以在web.xml中配)
引用
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>用户登录</h2>
<form action="user.html" method="post">
<input type="hidden" name="method" value="login">
用户名:<input name="username"><br>
密码:<input name="password" type="password"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>用户登录</h2>
<form action="user.html" method="post">
<input type="hidden" name="method" value="login">
用户名:<input name="username"><br>
密码:<input name="password" type="password"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
引用
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
登录成功!$user.username<br>
session:$request.session.getAttribute('user').username
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
登录成功!$user.username<br>
session:$request.session.getAttribute('user').username
</body>
</html>
4、访问http://localhost:8080/Veloctiy/user.html 一看就知道
总之:这个就是现在闲着没意思编着玩的,缺少很多功能(如上传,参数类型装换,还有对整个框架的扩展如插件化等等),跟成型的MVC Framework没法发,但是如果有人力、时间、金钱,相信我们国人也会编出相当完美优雅的框架。
还有一个月就毕业了,回望过去,还是很向往自己的大学生活,面对现实只能勇敢的去面对。
发表评论
-
转:用消息队列和消息应用状态表来消除分布式事务
2012-07-18 21:53 1508由于数据量的巨大,大 ... -
RRiBbit学习笔记
2012-07-17 21:42 5038RRiBbit可以作为事件总线Eventbus, 能够让组件之 ... -
安全发布原则
2012-04-18 21:48 1101public class XXX { private ... -
基于LinkedHashMap实现LRU缓存调度算法原理及应用
2011-11-29 21:02 18506最近手里事情不太多,随意看了看源码,在学习缓存技术的时候,都少 ... -
Java NIO Reactor模式
2011-10-11 15:57 4495package com.zzq.nio.reactor; ... -
并发控制—CAS
2011-07-07 23:55 1724public class AtomicIntegerTes ... -
压力测试JSON-RPC服务
2011-06-21 14:30 4010/** * 压力测试JSON-RPC服务 * * ... -
缓存失效算法比较
2011-06-13 20:03 1744提到缓存,有两点是必须要考虑的: 1、缓存数据和目标数据的一致 ... -
记录工作每阶段的代码质量——2011年2月20日
2011-02-20 23:45 1017package com.zzq.pattern.decorat ... -
另类的Singleton模式
2010-09-03 15:15 1079package com.zzq.singleton; /** ... -
我的各种主键生成策略类
2010-05-20 13:00 1703package com.generate; impo ... -
我的日志模型
2010-05-20 12:37 1222package com.zzq.logging; / ... -
Java模板引擎——Velocity应用实例(原创)
2010-02-10 21:18 2481对于b/s架构的项目而言,表示层呈现页面技术大多数选用jsp, ...
评论
EfsFrame就是一套基于Ajax技术实现的优秀的Java/.Net企业级框架,简单+实用+高效+稳定
开源下载地址:http://www.efsframe.cn/
大量的框架设计文档,帮助学习系统框架设计原理
慢慢就会习惯了.. 我都已经习惯了..JE上的大鸟们都是这样的!!
谢谢你的回复,呵呵 已经想通了 应有网友的话“自己专研知识、与人分享交流,最后得到进步,这才是王道”。
慢慢就会习惯了.. 我都已经习惯了..JE上的大鸟们都是这样的!!
谢谢你的回复,我会继续努力的!
这块还没做呢,现在只是个架子,解决重复提交,我的想法是定义一个Velocity的宏,页面input的时候,载入宏(就是往session中弄个值,页面有个hidden),到提价的action中进行比对session和表单hidden的值。
其实我说的是javaeye 回帖的时候手一抖 回了2个
呵呵 人无完人 何况论坛系统了
谢谢你的回复!我会努力的!
这块还没做呢,现在只是个架子,解决重复提交,我的想法是定义一个Velocity的宏,页面input的时候,载入宏(就是往session中弄个值,页面有个hidden),到提价的action中进行比对session和表单hidden的值。
其实我说的是javaeye 回帖的时候手一抖 回了2个
结果不是最重要的,代码也不是最重要的,设计思想才是最大的收获,以及研究的能力。
恭喜你,取得如此结果。
谢谢你的回复,愿我们一起努力,以后多多交流经验!
结果不是最重要的,代码也不是最重要的,设计思想才是最大的收获,以及研究的能力。
恭喜你,取得如此结果。
<div class="quote_div">
<div class="quote_title">woming66 写道</div>
<div class="quote_div">
<div class="quote_title">zhangshixi 写道</div>
<div class="quote_div">
<div class="quote_title">woming66 写道</div>
<div class="quote_div">为什么自己写的东西发上来却被评为“隐藏帖”,本意想把自己学习收获的成果分享一下,难道这还有什么错吗?评价“隐藏帖”的人,你们这样做让我很心寒!</div>
<br>写自己的博客、总结自己的知识,让别人去随意评论吧。其实大可不必在意这些,自己专研知识、与人分享交流,最后得到进步,这才是王道。<br>
</div>
<br>谢谢你的评价。您说的很对!自己专研知识、与人分享交流,最后得到进步,这才是王道。望以后继续交流!</div>
<p><br>我觉得这也许就是我们的心态吧,抛开万千世界不谈,只说在这么一个小小的社区中,其实已经繁琐复杂了:<br>有的人以看文章、学知识为乐;<br>有的人以总结知识、写博客为乐;<br>有的人以与人分享、交流为乐;<br>有的人以盲目追求点击率、人气为乐;<br>有的人以高高在上、傲视群雄为乐;<br>有的人以打发无聊、寂寞为乐<br>......<br>那么我们想想自己又属于哪种人呢?<br>也许当您看透了这些,任何鼓励、打击、甚至被人BS,都是过眼云烟罢了。</p>
<p> </p>
</div>
<p> </p>
<p>说的好!</p>
<div class="quote_div">
<div class="quote_title">zhangshixi 写道</div>
<div class="quote_div">
<div class="quote_title">woming66 写道</div>
<div class="quote_div">为什么自己写的东西发上来却被评为“隐藏帖”,本意想把自己学习收获的成果分享一下,难道这还有什么错吗?评价“隐藏帖”的人,你们这样做让我很心寒!</div>
<br>写自己的博客、总结自己的知识,让别人去随意评论吧。其实大可不必在意这些,自己专研知识、与人分享交流,最后得到进步,这才是王道。<br>
</div>
<br>谢谢你的评价。您说的很对!自己专研知识、与人分享交流,最后得到进步,这才是王道。望以后继续交流!</div>
<p><br>我觉得这也许就是我们的心态吧,抛开万千世界不谈,只说在这么一个小小的社区中,其实已经繁琐复杂了:<br>有的人以看文章、学知识为乐;<br>有的人以总结知识、写博客为乐;<br>有的人以与人分享、交流为乐;<br>有的人以盲目追求点击率、人气为乐;<br>有的人以高高在上、傲视群雄为乐;<br>有的人以打发无聊、寂寞为乐<br>......<br>那么我们想想自己又属于哪种人呢?<br>也许当您看透了这些,任何鼓励、打击、甚至被人BS,都是过眼云烟罢了。</p>
<p> </p>
这块还没做呢,现在只是个架子,解决重复提交,我的想法是定义一个Velocity的宏,页面input的时候,载入宏(就是往session中弄个值,页面有个hidden),到提价的action中进行比对session和表单hidden的值。
至于那些评隐藏的 不用理他们 中国人有个特点就是 越是下层的人的在获得一点点权利后就会去欺负比他们更下层的人来获得快感
呵呵 谢谢你的回复。我会继续努力的!
哦,不错哦!
我总觉着parse是个不可靠的东西——也许是错觉
不过如果能自己控制Velocity模板的缓存,细粒度的控制到页面片段的缓存,那就更好了
这个小弟弟,刚毕业就这么来塞,前途无量啊
不错,不错
谢谢你的回复!恩,这里的确有很多地方要改进,要重构的,随着今后的学习,我会继续完善它!
至于那些评隐藏的 不用理他们 中国人有个特点就是 越是下层的人的在获得一点点权利后就会去欺负比他们更下层的人来获得快感
至于那些评隐藏的 不用理他们 中国人有个特点就是 越是下层的人的在获得一点点权利后就会去欺负比他们更下层的人来获得快感