- 浏览: 485330 次
- 性别:
- 来自: 长沙
文章分类
最新评论
-
Source_野驴:
...
jsp静态化和伪静态化 -
zidanzzg:
很好的知识,找到了利用异或交换数值的理论支持,谢谢分享
XOR的性质和运算 -
ueseu:
引用(2) DomainDomain域名也是Cookie的一部 ...
Cookie的组成 -
ueseu:
引用Secure取true或者false值。如果为true,那 ...
Cookie的组成 -
liqi___123:
理解得很透彻,谢谢!!
ROLAP、MOLAP和HOLAP联机分析处理区别
RequestContext 这个类在 OSChina 中是非常重要的一个类,该类由全局 Filter 进行初始化,并传递给包括 Action 和 页面中直接使用,使用时通过 RequestContext.get() 来获取当前请求上下文实例。 这个方法主要的功能包括:自动转码、处理文件上传、登录信息处理,以及一些跟请求相关的常用方法封装。 如果你从中发现了什么问题,请不吝赐教。
package my.mvc; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import my.util.CryptUtils; import my.util.Multimedia; import my.util.RequestUtils; import my.util.ResourceUtils; import net.oschina.beans.User; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.Converter; import org.apache.commons.beanutils.converters.SqlDateConverter; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 请求上下文 * @author Winter Lau * @date 2010-1-13 下午04:18:00 */ public class RequestContext { private final static Log log = LogFactory.getLog(RequestContext.class); private final static int MAX_FILE_SIZE = 10*1024*1024; private final static String UTF_8 = "UTF-8"; private final static ThreadLocal<RequestContext> contexts = new ThreadLocal<RequestContext>(); private final static boolean isResin; private final static String upload_tmp_path; private final static String TEMP_UPLOAD_PATH_ATTR_NAME = "$OSCHINA_TEMP_UPLOAD_PATH$"; private static String webroot = null; private ServletContext context; private HttpSession session; private HttpServletRequest request; private HttpServletResponse response; private Map<String, Cookie> cookies; static { webroot = getWebrootPath(); isResin = _CheckResinVersion(); //上传的临时目录 upload_tmp_path = webroot + "WEB-INF" + File.separator + "tmp" + File.separator; try { FileUtils.forceMkdir(new File(upload_tmp_path)); } catch (IOException excp) {} //BeanUtils对时间转换的初始化设置 ConvertUtils.register(new SqlDateConverter(null), java.sql.Date.class); ConvertUtils.register(new Converter(){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); SimpleDateFormat sdf_time = new SimpleDateFormat("yyyy-M-d H:m"); @SuppressWarnings("rawtypes") public Object convert(Class type, Object value) { if(value == null) return null; if (value instanceof Date) return (value); try { return sdf_time.parse(value.toString()); } catch (ParseException e) { try { return sdf.parse(value.toString()); } catch (ParseException e1) { return null; } } }}, java.util.Date.class); } private final static String getWebrootPath() { String root = RequestContext.class.getResource("/").getFile(); try { root = new File(root).getParentFile().getParentFile().getCanonicalPath(); root += File.separator; } catch (IOException e) { throw new RuntimeException(e); } return root; } /** * 初始化请求上下文 * @param ctx * @param req * @param res */ public static RequestContext begin(ServletContext ctx, HttpServletRequest req, HttpServletResponse res) { RequestContext rc = new RequestContext(); rc.context = ctx; rc.request = _AutoUploadRequest(_AutoEncodingRequest(req)); rc.response = res; rc.response.setCharacterEncoding(UTF_8); rc.session = req.getSession(false); rc.cookies = new HashMap<String, Cookie>(); Cookie[] cookies = req.getCookies(); if(cookies != null) for(Cookie ck : cookies) { rc.cookies.put(ck.getName(), ck); } contexts.set(rc); return rc; } /** * 返回Web应用的路径 * @return */ public static String root() { return webroot; } /** * 获取当前请求的上下文 * @return */ public static RequestContext get(){ return contexts.get(); } public void end() { String tmpPath = (String)request.getAttribute(TEMP_UPLOAD_PATH_ATTR_NAME); if(tmpPath != null){ try { FileUtils.deleteDirectory(new File(tmpPath)); } catch (IOException e) { log.fatal("Failed to cleanup upload directory: " + tmpPath, e); } } this.context = null; this.request = null; this.response = null; this.session = null; this.cookies = null; contexts.remove(); } public Locale locale(){ return request.getLocale(); } public void closeCache(){ header("Pragma","No-cache"); header("Cache-Control","no-cache"); header("Expires", 0L); } /** * 自动编码处理 * @param req * @return */ private static HttpServletRequest _AutoEncodingRequest(HttpServletRequest req) { if(req instanceof RequestProxy) return req; HttpServletRequest auto_encoding_req = req; if("POST".equalsIgnoreCase(req.getMethod())){ try { auto_encoding_req.setCharacterEncoding(UTF_8); } catch (UnsupportedEncodingException e) {} } else if(!isResin) auto_encoding_req = new RequestProxy(req, UTF_8); return auto_encoding_req; } /** * 自动文件上传请求的封装 * @param req * @return */ private static HttpServletRequest _AutoUploadRequest(HttpServletRequest req){ if(_IsMultipart(req)){ String path = upload_tmp_path + RandomStringUtils.randomAlphanumeric(10); File dir = new File(path); if(!dir.exists() && !dir.isDirectory()) dir.mkdirs(); try{ req.setAttribute(TEMP_UPLOAD_PATH_ATTR_NAME,path); return new MultipartRequest(req, dir.getCanonicalPath(), MAX_FILE_SIZE, UTF_8); }catch(NullPointerException e){ }catch(IOException e){ log.fatal("Failed to save upload files into temp directory: " + path, e); } } return req; } public long id() { return param("id", 0L); } public String ip(){ return RequestUtils.getRemoteAddr(request); } @SuppressWarnings("unchecked") public Enumeration<String> params() { return request.getParameterNames(); } public String param(String name, String...def_value) { String v = request.getParameter(name); return (v!=null)?v:((def_value.length>0)?def_value[0]:null); } public long param(String name, long def_value) { return NumberUtils.toLong(param(name), def_value); } public int param(String name, int def_value) { return NumberUtils.toInt(param(name), def_value); } public byte param(String name, byte def_value) { return (byte)NumberUtils.toInt(param(name), def_value); } public String[] params(String name) { return request.getParameterValues(name); } public long[] lparams(String name){ String[] values = params(name); if(values==null) return null; return (long[])ConvertUtils.convert(values, long.class); } public String uri(){ return request.getRequestURI(); } public String contextPath(){ return request.getContextPath(); } public void redirect(String uri) throws IOException { response.sendRedirect(uri); } public void forward(String uri) throws ServletException, IOException { RequestDispatcher rd = context.getRequestDispatcher(uri); rd.forward(request, response); } public void include(String uri) throws ServletException, IOException { RequestDispatcher rd = context.getRequestDispatcher(uri); rd.include(request, response); } public boolean isUpload(){ return (request instanceof MultipartRequest); } public File file(String fieldName) { if(request instanceof MultipartRequest) return ((MultipartRequest)request).getFile(fieldName); return null; } public File image(String fieldname) { File imgFile = file(fieldname); return (imgFile!=null&&Multimedia.isImageFile(imgFile.getName()))?imgFile:null; } public boolean isRobot(){ return RequestUtils.isRobot(request); } public ActionException fromResource(String bundle, String key, Object...args){ String res = ResourceUtils.getStringForLocale(request.getLocale(), bundle, key, args); return new ActionException(res); } public ActionException error(String key, Object...args){ return fromResource("error", key, args); } /** * 输出信息到浏览器 * @param msg * @throws IOException */ public void print(Object msg) throws IOException { if(!UTF_8.equalsIgnoreCase(response.getCharacterEncoding())) response.setCharacterEncoding(UTF_8); response.getWriter().print(msg); } public void output_json(String[] key, Object[] value) throws IOException { StringBuilder json = new StringBuilder("{"); for(int i=0;i<key.length;i++){ if(i>0) json.append(','); boolean isNum = value[i] instanceof Number ; json.append("\""); json.append(key[i]); json.append("\":"); if(!isNum) json.append("\""); json.append(value[i]); if(!isNum) json.append("\""); } json.append("}"); print(json.toString()); } public void output_json(String key, Object value) throws IOException { output_json(new String[]{key}, new Object[]{value}); } public void error(int code, String...msg) throws IOException { if(msg.length>0) response.sendError(code, msg[0]); else response.sendError(code); } public void forbidden() throws IOException { error(HttpServletResponse.SC_FORBIDDEN); } public void not_found() throws IOException { error(HttpServletResponse.SC_NOT_FOUND); } public ServletContext context() { return context; } public HttpSession session() { return session; } public HttpSession session(boolean create) { return (session==null && create)?(session=request.getSession()):session; } public Object sessionAttr(String attr) { HttpSession ssn = session(); return (ssn!=null)?ssn.getAttribute(attr):null; } public HttpServletRequest request() { return request; } public HttpServletResponse response() { return response; } public Cookie cookie(String name) { return cookies.get(name); } public void cookie(String name, String value, int max_age, boolean all_sub_domain) { RequestUtils.setCookie(request, response, name, value, max_age, all_sub_domain); } public void deleteCookie(String name,boolean all_domain) { RequestUtils.deleteCookie(request, response, name, all_domain); } public String header(String name) { return request.getHeader(name); } public void header(String name, String value) { response.setHeader(name, value); } public void header(String name, int value) { response.setIntHeader(name, value); } public void header(String name, long value) { response.setDateHeader(name, value); } /** * 将HTTP请求参数映射到bean对象中 * @param req * @param beanClass * @return * @throws Exception */ public <T> T form(Class<T> beanClass) { try{ T bean = beanClass.newInstance(); BeanUtils.populate(bean, request.getParameterMap()); return bean; }catch(Exception e) { throw new ActionException(e.getMessage()); } } /** * 返回当前登录的用户资料 * @return */ public IUser user() { return User.GetLoginUser(request); } /** * 保存登录信息 * @param req * @param res * @param user * @param save */ public void saveUserInCookie(IUser user, boolean save) { String new_value = _GenLoginKey(user, ip(), header("user-agent")); int max_age = save ? MAX_AGE : -1; deleteCookie(COOKIE_LOGIN, true); cookie(COOKIE_LOGIN,new_value,max_age,true); } public void deleteUserInCookie() { deleteCookie(COOKIE_LOGIN, true); } /** * 3.0 以上版本的 Resin 无需对URL参数进行转码 * @return */ private final static boolean _CheckResinVersion() { try{ Class<?> verClass = Class.forName("com.caucho.Version"); String ver = (String)verClass.getDeclaredField("VERSION").get(verClass); String mainVer = ver.substring(0, ver.lastIndexOf('.')); /** float fVer = Float.parseFloat(mainVer); System.out.println("----------------> " + fVer); */ return Float.parseFloat(mainVer) > 3.0; }catch(Throwable t) {} return false; } /** * 自动解码 * @author liudong */ private static class RequestProxy extends HttpServletRequestWrapper { private String uri_encoding; RequestProxy(HttpServletRequest request, String encoding){ super(request); this.uri_encoding = encoding; } /** * 重载getParameter */ public String getParameter(String paramName) { String value = super.getParameter(paramName); return _DecodeParamValue(value); } /** * 重载getParameterMap */ @SuppressWarnings({ "unchecked", "rawtypes" }) public Map<String, Object> getParameterMap() { Map params = super.getParameterMap(); HashMap<String, Object> new_params = new HashMap<String, Object>(); Iterator<String> iter = params.keySet().iterator(); while(iter.hasNext()){ String key = (String)iter.next(); Object oValue = params.get(key); if(oValue.getClass().isArray()){ String[] values = (String[])params.get(key); String[] new_values = new String[values.length]; for(int i=0;i<values.length;i++) new_values[i] = _DecodeParamValue(values[i]); new_params.put(key, new_values); } else{ String value = (String)params.get(key); String new_value = _DecodeParamValue(value); if(new_value!=null) new_params.put(key,new_value); } } return new_params; } /** * 重载getParameterValues */ public String[] getParameterValues(String arg0) { String[] values = super.getParameterValues(arg0); for(int i=0;values!=null&&i<values.length;i++) values[i] = _DecodeParamValue(values[i]); return values; } /** * 参数转码 * @param value * @return */ private String _DecodeParamValue(String value){ if (StringUtils.isBlank(value) || StringUtils.isBlank(uri_encoding) || StringUtils.isNumeric(value)) return value; try{ return new String(value.getBytes("8859_1"), uri_encoding); }catch(Exception e){} return value; } } private static boolean _IsMultipart(HttpServletRequest req) { return ((req.getContentType() != null) && (req.getContentType() .toLowerCase().startsWith("multipart"))); } /** * 生成用户登录标识字符串 * @param user * @param ip * @param user_agent * @return */ public static String _GenLoginKey(IUser user, String ip, String user_agent) { StringBuilder sb = new StringBuilder(); sb.append(user.getId()); sb.append('|'); sb.append(user.getPwd()); sb.append('|'); sb.append(ip); sb.append('|'); sb.append((user_agent==null)?0:user_agent.hashCode()); sb.append('|'); sb.append(System.currentTimeMillis()); return _Encrypt(sb.toString()); } /** * 加密 * @param value * @return * @throws Exception */ private static String _Encrypt(String value) { byte[] data = CryptUtils.encrypt(value.getBytes(), E_KEY); try{ return URLEncoder.encode(new String(Base64.encodeBase64(data)), UTF_8); }catch(UnsupportedEncodingException e){ return null; } } /** * 解密 * @param value * @return * @throws Exception */ private static String _Decrypt(String value) { try { value = URLDecoder.decode(value,UTF_8); if(StringUtils.isBlank(value)) return null; byte[] data = Base64.decodeBase64(value.getBytes()); return new String(CryptUtils.decrypt(data, E_KEY)); } catch (UnsupportedEncodingException excp) { return null; } } /** * 从cookie中读取保存的用户信息 * @param req * @return */ public IUser getUserFromCookie() { try{ Cookie cookie = cookie(COOKIE_LOGIN); if(cookie!=null && StringUtils.isNotBlank(cookie.getValue())){ return userFromUUID(cookie.getValue()); } }catch(Exception e){} return null; } /** * 从cookie中读取保存的用户信息 * @param req * @return */ public IUser userFromUUID(String uuid) { if(StringUtils.isBlank(uuid)) return null; String ck = _Decrypt(uuid); final String[] items = StringUtils.split(ck, '|'); if(items.length == 5){ String ua = header("user-agent"); int ua_code = (ua==null)?0:ua.hashCode(); int old_ua_code = Integer.parseInt(items[3]); if(ua_code == old_ua_code){ return new IUser(){ public boolean IsBlocked() { return false; } public long getId() { return NumberUtils.toLong(items[0],-1L); } public String getPwd() { return items[1]; } public byte getRole() { return IUser.ROLE_GENERAL; } }; } } return null; } public final static String COOKIE_LOGIN = "oscid"; private final static int MAX_AGE = 86400 * 365; private final static byte[] E_KEY = new byte[]{'1','2','3','4','5','6','7','8'}; }
RequestContext的用例的全局过滤器源码:
package my.mvc; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import my.db.DBManager; /** * 全局过滤器 * @author Winter Lau * @date 2010-1-13 下午08:36:18 */ public class ControllerFilter implements Filter { private ServletContext context; /** * 过滤器初始化 */ public void init(FilterConfig cfg) throws ServletException { this.context = cfg.getServletContext(); } /** * 执行过滤操作 */ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; RequestContext rc = RequestContext.begin(this.context, request, response); if(rc.uri().indexOf("/.svn/")>=0){ rc.forbidden(); return ; } try{ chain.doFilter(rc.request(), rc.response()); }finally{ if(rc!=null) rc.end(); DBManager.closeConnection(); } } /** * 过滤器释放资源 */ public void destroy() { } }
发表评论
-
消息中间件和JMS
2013-06-03 10:21 813当前,CORBA、DCOM、RMI等 ... -
失血模型-贫血模型-充血模型-胀血模型
2012-07-20 13:21 2089一、失血模型 失血模型简单来说,就是domain ob ... -
JSP中文验证码
2012-05-14 17:18 1245以上两篇文章的内容介绍了有关JSP中产生数字验证码跟中文验证 ... -
Javamail中的常见中文乱码问题与解决办法
2011-09-09 09:48 1658在使用javamail api开发邮件服务系统时,我们常常会碰 ... -
ZK框架简介
2011-07-21 08:08 13681、ZK框架简介 ZK框架是 ... -
Tiles使用简介
2011-06-23 14:32 1260最新喜欢看一看一些比较“老旧”的技术,感觉这些 ... -
Apache Commons DbUtils快速上手
2011-06-18 10:58 1371最近喜欢看一些技术比较“老旧”的东西,虽然所实现的技术老 ... -
Xdoclet用于servlet
2011-03-24 11:26 858web.xm和taglib 作servlet映射是个讨厌的工 ... -
JSF生命周期监听
2011-03-11 18:10 1265这里有一点代码, 一个 PhaseListener ... -
自定义jsp标记库简介
2011-03-11 18:08 8131. 基本步骤 实例-输出“hello,eking” 1) ... -
组合Servlet+Freemarker的两种方法
2011-03-06 12:52 1504Servlet的轻巧高效,Freemarker的强大简便 ... -
Apache开源项目分类列表
2011-01-12 15:45 1067分类 项目名 说明 开发 ... -
myeclipse快捷键
2010-11-26 09:45 773MyEclipse 快捷键[转载] ... -
MyEclipse Content Assist
2010-11-26 09:39 1048问题描述: 在使用MyEclipse 6中不能使用 al ... -
删除eclipse的configuration目录
2010-07-07 10:27 3136eclipse 3.4以前的版本,如果出现什么问题了, ... -
JasperReports和iReport制作报表
2010-06-25 13:40 1367最近使用了JasperReports ... -
Lucene版Hello world
2010-06-04 18:38 19591、首先从lucene官网上下载lucene2.4.0(也可以 ... -
用p6spy查看HIBERNATE生成的SQL
2010-06-02 15:52 2185P6Spy是一个可以用来在应用程序中拦截和修改数据操作 ... -
hibernate id Generator详解
2010-06-02 15:16 1335Hibernate中,<id>标签 ...
相关推荐
- 了解一个大型Android项目的目录结构是非常重要的。通常,一个Android项目会包含`app/src/main/java`(源代码)、`res`(资源文件)、`build.gradle`(构建配置)等多个关键部分。通过分析OSChina客户端的源码,你...
理解Service的生命周期和使用方式,对于提升应用的性能和用户体验至关重要。 BroadcastReceiver用于监听系统或自定义广播事件,如网络状态变化或特定消息到达。在OSChina客户端中,BroadcastReceiver可能用于监听...
1. `AsyncTask`:Android内置的异步任务类,用于执行后台操作并更新UI。 2. `Handler/Looper`:消息处理系统,用于在主线程中处理异步操作的结果。 3. `RxJava`:响应式编程库,提供更灵活的异步处理和事件驱动编程...
1. **默认文件**:创建完成后,您将看到项目仓库中已经包含了两个默认文件(通常是README.md和LICENSE文件),这些文件对于项目来说非常重要。 2. **获取Git地址**:在项目页面中,您可以找到项目的Git地址,一般...
对于大型系统,日志管理和监控至关重要。源码可能涉及Log4j、Logback等日志框架,以及Prometheus、ELK Stack(Elasticsearch、Logstash、Kibana)等监控解决方案。 总之,通过深入研究OSChina的源码,开发者不仅...
4. **网络请求**:OSChina客户端可能使用了URLSession或者第三方库如Alamofire进行网络数据的获取,了解如何处理API请求、解析JSON数据是重要的一环。 5. **数据持久化**:客户端可能采用了Core Data或SQLite来存储...
资源名称:oschina(开源社区)技术架构介绍内容简介:每日访问统计数据总览IP > 10w动态请求接近 300w 页面请求 80w,Ajax请求 220w高峰期并发连接数 2000oschina 硬件配置DELL SC 1435 (1台) CPU: 双 AMD 2G 内存:...
总之,通过研究OSChina Android App 2.2.1的源码,开发者不仅可以提升Android开发技能,还能学习到项目管理、性能优化、安全防护等多个方面的知识,这对于个人成长和团队协作都有着重要的价值。因此,深入源码,是每...
3. **Java类**(如:MainActivity.java):实现了应用的主要逻辑,包括Activity的生命周期方法、事件处理和业务逻辑。 4. **网络请求**:可能使用了HttpURLConnection、OkHttp、Volley或Retrofit等库来处理网络请求...
oschina+技术架构介绍
AppCompatActivity是AppCompat库中的关键类,它扩展了ActionBarActivity(或现在是FragmentActivity),提供了Material Design风格的ActionBar和ToolBar。 3. **用户界面设计**:客户端的设计遵循Android Material ...
OSChina 已开源的所有源码包括jar 下载
客户端(Client)或称为...对于这一类应用程序,需要网络中有相应的服务器和服务程序来提供相应的服务,如数据库服务,电子邮件服务等等,这样在客户机和服务器端,需要建立特定的通信连接,来保证应用程序的正常运行。
在【oschina-app】源码中,我们可以深入研究以下几个重要的知识点: 1. **数据存储**:在Android平台上,数据存储有多种方式,包括SQLite数据库、SharedPreferences、文件存储、ContentProvider等。oschina-app可能...
对于初学者来说,重点在于熟练掌握Git的基础知识和操作技巧,这对于后续的高效协作开发至关重要。随着Git在软件开发领域中的广泛应用,熟悉并掌握其使用方法,将有助于提升个人和团队的工作效率。
在“oschina-android-app”中,我们可能会找到处理网络请求的相关类,如OkHttpUtils或RetrofitUtils。 五、数据库操作 为了存储用户偏好设置或者离线缓存数据,Android应用通常会使用SQLite数据库。开源中国应用...
【标题】"oschina-android-app(开源中国)"是一个基于Android平台的应用程序源代码,它提供了访问开源中国网站的功能,让开发者能够深入了解Android应用开发的内部机制和实践。开源中国作为一个国内知名的开源技术...
DotNetOpenAuth.OSChinaOAuth2 是 DotNetOpenAuth的OSChina登陆扩展。 安装: 1.通过 NuGut 安装 PM> Install-Package DotNetOpenAuth.OSChinaOAuth2 ...OAuthWebSecurity.RegisterClient(client, "OSChina");