- 浏览: 277010 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
u014704612:
你好,请问这个实现由需要什么条件吗,我复制进去达不到全屏的效果 ...
JavaScript控制页面全屏,并且禁止使用ALT+TAB键切换 -
shengtu:
能不能兼容其它浏览器呢?
JavaScript控制页面全屏,并且禁止使用ALT+TAB键切换 -
leongfeng:
xd_fjx 写道如果使用那个HibernateCallbac ...
Spring中使用HibernateCallback -
soft5200:
jQuery.getJSON('http://localhos ...
使用JQuery结合HIghcharts实现从后台获取JSON实时刷新图表 -
monica617:
讲的还可以字体和格式再设置为易读模式就更好了
Struts1.3.x中ActionServlet源码分析之执行
执行流程:
1、ActionServlet处理.do的请求 不管是get还是post方式都将转到
protected void process(HttpServletRequest request, HttpServletResponse response) 方法。
2、根据请求对象和servletContext对象选择请求所隶属的模块
ModuleUtils.getInstance().selectModule(request, getServletContext());
3、加载模块配置对象 ModuleConfig config = getModuleConfig(request);
4、加载请求处理对象
RequestProcessor processor = getProcessorForModule(config);
if (processor == null) {
processor = getRequestProcessor(config);
}
5、调用请求对象(processor)对象的
public void process(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
方法处理请求。
6、对mutipart请求(上传)进行特殊包装 request = processMultipart(request);
1、首先判断是否为post方式,如果不是post方式,则肯定不是上传请求,则直接返回request对象
if (!"POST".equalsIgnoreCase(request.getMethod())) {
return (request);
}
2、获取request对象的ContentType,如果ContentType为multipart/form-datade 话则 new 一个 MultipartRequestWrapper 对象返回。否则直接返回request。
String contentType = request.getContentType();
if ((contentType != null)
&& contentType.startsWith("multipart/form-data")) {
return (new MultipartRequestWrapper(request));
} else {
return (request);
}
1、MultipartRequestWrapper继承于HttpServletRequestWrapper。下面是包装代码
public MultipartRequestWrapper(HttpServletRequest request) {
super(request);
this.parameters = new HashMap();
}
7、处理请求路径
String path = processPath(request, response); 返回的是访问的action的名字
8、如果返回值是空, 则方法直接return,结束。
if (path == null) {
return;
}
9、把请求的方式(post/get)和action名字记入日志
if (log.isDebugEnabled()) {
log.debug("Processing a '" + request.getMethod() + "' for path '"
+ path + "'");
}
10、为当前的用户请求选择对应的local(区域和语言),这是根据浏览器的设置的。涉及到国际化问题。
// Select a Locale for the current user if requested
processLocale(request, response);
11、为response对象设置ContentType和no-cache的header信息。
// Set the content type and no-caching headers if requested
processContent(request, response);
processNoCache(request, response);
12、留了一个可以预处理请求的扩展接口。
// General purpose preprocessing hook
if (!processPreprocess(request, response)) {
return;
} 这里processPreprocess方法只有一句话:return(true);其实是为了可以扩展,如果要对请求预处理,可以继承这个类,然后重写这个
protected boolean processPreprocess(HttpServletRequest request,HttpServletResponse response) {
return (true);
}
方法。
13、处理以前缓存的信息
this.processCachedMessages(request, response);
其实就是清空session里如果存在的struts定义的提示信息和错误信息。
14、根据request,response,和path(action的名字)返回actionMapping对象。
// Identify the mapping for this request
ActionMapping mapping = processMapping(request, response, path);
if (mapping == null) {
return;
}
1、首先去配置文件里找相应的配置信息
// Is there a mapping for this path?
ActionMapping mapping = (ActionMapping) moduleConfig.findActionConfig(path);
2、如果有配置则把它放入request,并返回他。
// If a mapping is found, put it in the request and return it
if (mapping != null) {
request.setAttribute(Globals.MAPPING_KEY, mapping);
return (mapping);
}
3、找到“未知的映射路径(如果有的话)”。同样找到了就放到request里并返回他。
// Locate the mapping for unknown paths (if any)
ActionConfig[] configs = moduleConfig.findActionConfigs();
for (int i = 0; i < configs.length; i++) {
if (configs[i].getUnknown()) {
mapping = (ActionMapping) configs[i];
request.setAttribute(Globals.MAPPING_KEY, mapping);
return (mapping);
}
}
4、如果还是没有找到mapping信息则发送错误消息,并返回null
// No mapping can be found to process this request
String msg = getInternal().getMessage("processInvalid");
log.error(msg + " " + path);
response.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
return null;
15、检查执行这个action所要的所有角色(是否有权访问)
// Check for any role required to perform this action
if (!processRoles(request, response, mapping)) {
return;
}
1、从actionMapping(mapping)对想里取得角色名称的数组。
// Is this action protected by role requirements?
String[] roles = mapping.getRoleNames();
2、如果mapping里没有角色信息(没有配置),就不做处理,直接返回true
if ((roles == null) || (roles.length < 1)) {
return (true);
}
3、依次取出配置了的角色 ,如果用户在角色中 (配置了的所有角色中的任意一个) ,则把用户名和角色名记 录到log里。并返回true。
// Check the current user against the list of required roles
for (int i = 0; i < roles.length; i++) {
if (request.isUserInRole(roles[i])) {
if (log.isDebugEnabled()) {
log.debug(" User '" + request.getRemoteUser()
+ "' has role '" + roles[i] + "', granting access");
}
return (true);
}
}
4、如果仍没找到用户所对应的角色,则说明这个用户是非法访问的。则把这个用户名记录到log里,发送错误信息,并返回false。
// The current user is not authorized for this action
if (log.isDebugEnabled()) {
log.debug(" User '" + request.getRemoteUser()
+ "' does not have any required role, denying access");
}
response.sendError(HttpServletResponse.SC_FORBIDDEN,
getInternal().getMessage("notAuthorized", mapping.getPath()));
return (false);
16、处理与这个请求有关的所有actionForm。(调用processActionForm()方法返回ActionForm对象)
// Process any ActionForm bean related to this request
ActionForm form = processActionForm(request, response, mapping);
1、如果有需要就新建一个ActionForm来供使用。
// Create (if necessary) a form bean to use
ActionForm instance = RequestUtils.createActionForm(request, mapping, moduleConfig, servlet);
1、查看mapping里是否配置name属性或attribute属性来指定ActionForm,如果都没有则返回null
// Is there a form bean associated with this mapping?
String attribute = mapping.getAttribute();
if (attribute == null) {
return (null);
}
2、通过name属性拿到ActionForm的配置信息
// Look up the form bean configuration information to use
String name = mapping.getName();
FormBeanConfig config = moduleConfig.findFormBeanConfig(name);
3、如果没有与name属性相对应的<form-bean>配置,则在log里记录:没有配置与name对应的formBean,并返回null;
if (config == null) {
log.warn("No FormBeanConfig found under '" + name + "'");
return (null);
}
4、根据拿到的<form-bean>配置,在相应的范围里(request,session)找ActionForm的实例
ActionForm instance = lookupActionForm(request, attribute, mapping.getScope());
5、如果找到,并被判定为可用,则返回找到的实例。
// Can we recycle the existing form bean instance (if there is one)?
if ((instance != null) && config.canReuse(instance)) {
return (instance);
}
6、如果没找到,(前面已经确定配置了formBean)。则新建一个ActionForm对象出来并返回他。
return createActionForm(config, servlet);
1、首先判断传入的config,如果config为null,则直接返回null
if (config == null) {
return (null);
}
2、创建并返回一个新的ActionForm对象。这里调用了config对象的createActionForm方法。该方法里肯定用到了反射机制。另外把创建的ActionForm或动态ActionForm的信息存到log里。同样,如果过程中出错,错误信息业将被保存到日志里。
ActionForm instance = null;
// Create and return a new form bean instance
try {
instance = config.createActionForm(servlet);
if (log.isDebugEnabled()) {
log.debug(" Creating new "
+ (config.getDynamic() ? "DynaActionForm" : "ActionForm")
+ " instance of type '" + config.getType() + "'");
log.trace(" --> " + instance);
}
} catch (Throwable t) {
log.error(servlet.getInternal().getMessage("formBean",
config.getType()), t);
}
return (instance);
17、为ActionForm填充数据。
processPopulate(request, response, form, mapping);
1、首先判断form是否为null,如果是则直接return。
if (form == null) {
return;
}
2、往log里写入一句话提示从这里开始填充formBean
if (log.isDebugEnabled()) {
log.debug(" Populating bean properties from this request");
}
3、设置Servlet。
form.setServlet(this.servlet);
(不知道具体作用)
4、执行reset方法重置表单。默认reset方法不做任何事情。这个方法是为了方便扩展。可以继承ActionForm类重写reset方法,这个方法可以用来做设置一些默认值等工作。
form.reset(mapping, request);
5、如果是上传表单,则获取上传类。(不甚了解)
if (mapping.getMultipartClass() != null) {
request.setAttribute(Globals.MULTIPART_KEY,
mapping.getMultipartClass());
}
6、填充form
RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix(), request);
1、建立一个HashMap 用于存放属性
// Build a list of relevant request parameters from this request
HashMap properties = new HashMap();
2、建立一个Enumeration用于存放参数名
// Iterator of parameter names
Enumeration names = null;
3、建立一个Map来存放multipart参数
// Map for multipart parameters
Map multipartParameters = null;
4、获取请求的ContentType和Method。并设置multipart表示为false。
String contentType = request.getContentType();
String method = request.getMethod();
boolean isMultipart = false;
5、如果是multipart表单则做上传处理(不甚了解)
if (bean instanceof ActionForm) {
((ActionForm) bean).setMultipartRequestHandler(null);
}
MultipartRequestHandler multipartHandler = null;
if ((contentType != null)
&& (contentType.startsWith("multipart/form-data"))
&& (method.equalsIgnoreCase("POST"))) {
// Get the ActionServletWrapper from the form bean
ActionServletWrapper servlet;
if (bean instanceof ActionForm) {
servlet = ((ActionForm) bean).getServletWrapper();
} else {
throw new ServletException("bean that's supposed to be "
+ "populated from a multipart request is not of type "
+ "\"org.apache.struts.action.ActionForm\", but type "
+ "\"" + bean.getClass().getName() + "\"");
}
// Obtain a MultipartRequestHandler
multipartHandler = getMultipartHandler(request);
if (multipartHandler != null) {
isMultipart = true;
// Set servlet and mapping info
servlet.setServletFor(multipartHandler);
multipartHandler.setMapping((ActionMapping) request
.getAttribute(Globals.MAPPING_KEY));
// Initialize multipart request class handler
multipartHandler.handleRequest(request);
//stop here if the maximum length has been exceeded
Boolean maxLengthExceeded =
(Boolean) request.getAttribute(MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);
if ((maxLengthExceeded != null)
&& (maxLengthExceeded.booleanValue())) {
((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
return;
}
//retrieve form values and put into properties
multipartParameters =
getAllParametersForMultipartRequest(request,
multipartHandler);
names = Collections.enumeration(multipartParameters.keySet());
}
}
6、如果不是上传,则把参数名存到names枚举里面。
if (!isMultipart) {
names = request.getParameterNames();
}
7、遍历这个枚举
while (names.hasMoreElements())
1、把名字拿出来存到name和stripped变量里
String name = (String) names.nextElement();
String stripped = name;
2、去掉name的前缀和后缀(如果有的话(配置文件里可以配置))
if (prefix != null) {
if (!stripped.startsWith(prefix)) {
continue;
}
stripped = stripped.substring(prefix.length());
}
if (suffix != null) {
if (!stripped.endsWith(suffix)) {
continue;
}
stripped =
stripped.substring(0, stripped.length() - suffix.length());
}
3、获取参数值,分上传和非上传两种方式
Object parameterValue = null;
if (isMultipart) {
parameterValue = multipartParameters.get(name);
parameterValue = rationalizeMultipleFileProperty(bean, name, parameterValue);
} else {
parameterValue = request.getParameterValues(name);
}
4、如果参数名去掉了前后缀后不是一org.Apache.struts开头则把参数存到定义好的HashMap里
// Populate parameters, except "standard" struts attributes
// such as 'org.apache.struts.action.CANCEL'
if (!(stripped.startsWith("org.apache.struts."))) {
properties.put(stripped, parameterValue);
}
8、调用BeanUtils的方法把formBean的属性填充进去(异常处理那块不是很明白)
// Set the corresponding properties of our bean
try {
BeanUtils.populate(bean, properties);
} catch (Exception e) {
throw new ServletException("BeanUtils.populate", e);
} finally {
if (multipartHandler != null) {
// Set the multipart request handler for our ActionForm.
// If the bean isn't an ActionForm, an exception would have been
// thrown earlier, so it's safe to assume that our bean is
// in fact an ActionForm.
((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
}
}
7、加入合适的话就把退出属性设置到request里;(还是不了解)
// Set the cancellation request attribute if appropriate
if ((request.getParameter(Globals.CANCEL_PROPERTY) != null)
|| (request.getParameter(Globals.CANCEL_PROPERTY_X) != null)) {
request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);
}
18、验证表单输入的合法性。如果有不合法的则return。(一般不用struts的表单级验证)
// Validate any fields of the ActionForm bean, if applicable
try {
if (!processValidate(request, response, form, mapping)) {
return;
}
} catch (InvalidCancelException e) {
ActionForward forward = processException(request, response, e, form, mapping);
processForwardConfig(request, response, forward);
return;
} catch (IOException e) {
throw e;
} catch (ServletException e) {
throw e;
}
19、处理mapping指定的forward 和 include
// Process a forward or include specified by this mapping
if (!processForward(request, response, mapping)) {
return;
}
if (!processInclude(request, response, mapping)) {
return;
}
20、创建或者获取一个Action的实例来处理请求。
// Create or acquire the Action instance to process this request
Action action = processActionCreate(request, response, mapping);
1、从mapping里取出配置的Action类名
// Acquire the Action instance we will be using (if there is one)
String className = mapping.getType();
2、把查找Action实例的动作记入到日志里
if (log.isDebugEnabled()) {
log.debug(" Looking for Action instance for class " + className);
}
3、在拿到Action实例之前先线程同步synchronized (actions) ,保证只有一个Action实例
4、从map里取出Action返回,(如果有的话),并把结果写入日志
nstance = (Action) actions.get(className);
if (instance != null) {
if (log.isTraceEnabled()) {
log.trace(" Returning existing Action instance");
}
return (instance);
}
5、如果上面的操作没进行,那说明要新建一个Action实例,把新建实例的动作记录到日志里
if (log.isTraceEnabled()) {
log.trace(" Creating new Action instance");
}
6、创建出Action实例,吧实例放到map里并返回实例
try {
instance = (Action) RequestUtils.applicationInstance(className);
// Maybe we should propagate this exception
// instead of returning null.
} catch (Exception e) {
log.error(getInternal().getMessage("actionCreate",
mapping.getPath()), e);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
getInternal().getMessage("actionCreate", mapping.getPath()));
return (null);
}
actions.put(className, instance);
if (instance.getServlet() == null) {
instance.setServlet(this.servlet);
}
}
return (instance);
21、再次判断Action是否创建成功,如果没有则方法直接return
if (action == null) {
return;
}
22、执行Action的excute方法,获得ActionForward
// Call the Action instance itself
ActionForward forward = processActionPerform(request, response, action, form, mapping);
其中processActionPerform方法调用了action的excute方法:
protected ActionForward processActionPerform(HttpServletRequest request,
HttpServletResponse response, Action action, ActionForm form,
ActionMapping mapping)
throws IOException, ServletException {
try {
return (action.execute(mapping, form, request, response));
} catch (Exception e) {
return (processException(request, response, e, form, mapping));
}
}
这里也做了一个处理,如果要在执行excute方法之前做一些操作,就可以覆盖processActionPerform方法。
23、更具Actionforward进行转发
// Process the returned ActionForward instance
processForwardConfig(request, response, forward);
1、如果ActionForward为空,则方法直接返回
if (forward == null) {
return;
}
2、把接下来处理forward的操作记录到日志里
if (log.isDebugEnabled()) {
log.debug("processForwardConfig(" + forward + ")");
}
3、从mapping里获取forward对应的url,默认用forward的方式转发,如果配了redirect,则用redirect重定向
String forwardPath = forward.getPath();
String uri;
// If the forward can be unaliased into an action, then use the path of the action
String actionIdPath = RequestUtils.actionIdURL(forward, request, servlet);
if (actionIdPath != null) {
forwardPath = actionIdPath;
ForwardConfig actionIdForward = new ForwardConfig(forward);
actionIdForward.setPath(actionIdPath);
forward = actionIdForward;
}
// paths not starting with / should be passed through without any
// processing (ie. they're absolute)
if (forwardPath.startsWith("/")) {
// get module relative uri
uri = RequestUtils.forwardURL(request, forward, null);
} else {
uri = forwardPath;
}
if (forward.getRedirect()) {
// only prepend context path for relative uri
if (uri.startsWith("/")) {
uri = request.getContextPath() + uri;
}
response.sendRedirect(response.encodeRedirectURL(uri));
} else {
doForward(uri, request, response);
}
相关推荐
基于springboot大学生就业信息管理系统源码数据库文档.zip
基于java的驾校收支管理可视化平台的开题报告
时间序列 原木 间隔5秒钟 20241120
毕业设计&课设_基于 Vue 的电影在线预订与管理系统:后台 Java(SSM)代码,为毕业设计项目.zip
基于springboot课件通中小学教学课件共享平台源码数据库文档.zip
基于java的网上购物商城的开题报告
Delphi人脸检测与识别Demo1fdef-main.zip
基于java的咖啡在线销售系统的开题报告
基于java的自助医疗服务系统的开题报告.docx
内容概要:本文档全面介绍了Visual Basic(VB)编程语言的基础知识和高级应用。首先概述了VB的基本特性和开发环境,随后详细讲述了VB的数据类型、变量、运算符、控制结构、数组、过程与函数、变量作用域等内容。接着介绍了窗体设计、控件使用、菜单与工具栏的设计,文件操作、数据库访问等关键知识点。最后讨论了VB的学习方法、发展历史及其在桌面应用、Web应用、数据库应用、游戏开发和自动化脚本编写等领域的广泛应用前景。 适合人群:初学者和中级程序员,尤其是希望快速掌握Windows桌面应用开发的人群。 使用场景及目标:①掌握VB的基础语法和开发环境;②学会使用VB创建复杂的用户界面和功能完整的应用程序;③理解数据库操作、文件管理和网络编程等高级主题。 其他说明:Visual Basic是一种简单易学且功能强大的编程语言,尤其适合用于开发Windows桌面应用。文中不仅覆盖了基础知识,还包括了大量的实用案例和技术细节,帮助读者快速提升编程技能。
基于java的疫情期间高校防控系统开题报告.docx
基于springboot+vue社区老年人帮扶系统源码数据库文档.zip
基于java的超市商品管理系统的开题报告.docx
基于SpringBoot房屋买卖平台源码数据库文档.zip
xdu限通院23微处理器系统与应用大作业(两只老虎),适应于汇编语言keil软件,
<项目介绍> - 新闻类网站系统,基于SSM(Spring、Spring MVC、MyBatis)+MySQL开发,高分成品毕业设计,附带往届论文 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
基于java的学生网上请假系统的开题报告.docx
社会经济繁荣发展的今天,电子商务得到了飞速发展,网上交易越来越彰显出其独特的优越性,在人们的日常生活中,出现了各种类型的交易网站。其中一个就是车辆易主交易网站,它是一个服务于用户买卖二手车辆的交易网站,为用户提供了平等互利、方便快捷的网上交易平台,通过这一类型的网站,用户可自由出售和购买车辆。 本课题主要根据车辆本身的特性,充分发挥互联网的特点与优势,构建一个以二手车辆为商品、基于互联网平台的车辆易主业务交易管理系统,并根据车辆易主业务交易管理系统的应用需求,进行需求分析,进而对网站系统作规划设计。采用IDEA为运行平台,以SSH为框架,运用HTML语言、JSP技术、MySql数据库、JSP与后台数据库链接等关键技术建设二手车网上交易系统,构建车辆易主交易系统的会员注册与登录,网站首页展示、用户发布商品车辆,用户求购商品车辆,分页浏览、购物系统、用户后台管理、管理员用户后台管理等功能,并使这些功能得以实现并更好为用户服务。网站整体构建完成且测试成功后,用户可以进入网站进行注册、登录,登录后,用户可以在网站上发布自己的闲置车辆或者寻找想要购买的车辆,还可以收藏车辆,管理发布和收藏的车辆,
SQLite3的向量扩展库,windows dll,版本0.1.5
基于C++实现(控制台)商品库存管理系统