首页 文章 精选 留言 我的

精选列表

搜索[子流程],共10000篇文章
优秀的个人博客,低调大师

mac或linux下安装hadoop-2.8流程

mac上安装hadoop 1,mac下的java ll /usr/bin |grep'java' 默认: /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java 具体的安装路径: /Library/Java/JavaVirtualMachines/下面, JAVA_HOME是/Library/Java/JavaVirtualMachines/jdk1.7.0_75/Contents/Home。 2,mac下的ssh 首先测试ssh localhost, 若不成功,看是否启动允许remotelogin,再尝试如果失败则继续下面的 ssh-keygen -t dsa-P '' -f ~/.ssh/id_dsa ssh-keygen表示生成秘钥; -t表示秘钥类型;-P用于提供密语;-f指定生成的秘钥文件。 这个命令在”~/.ssh/“文件夹下创建两个文件id_dsa和id_dsa.pub,是ssh的一对儿私钥和公钥。 接下来,将公钥追加到授权的key中去,输入: cat~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys 再次尝试 ssh localhost 若无法打开,解决方法如下: 进入Mac的系统偏好设置 –> 共享–> 勾选remote login,并设置allow access for all users。 3,下载镜像,mirror,选择某一个tar.gz http://mirror.bit.edu.cn/apache/hadoop/common/ 4,设置环境变量 vi ~/.bash_profile 或者/etc/profile中 exportJAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_75/Contents/Home exportJRE_HOME=$JAVA_HOME/jre exportHADOOP_HOME=/Users/xiaolong.zhao/ittools/hadoop #是防止出现:Warning:$HADOOP_HOME is deprecated的警告错误。 exportHADOOP_HOME_WARN_SUPPRESS=1 exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin: $ HADOOP_HOME /sbin:$HADOOP_HOME/bin:$PATH 注意:linux与mac的安装,唯一区别就是mac下会有默认的jdk路径的,以及ssh配置的 5,配置hadoop-env.sh 在/Users/xiaolong.zhao/ittools/hadoop/etc/hadoop目录下,找到hadoop-env.sh,打开编辑进行如下设置: export JAVA_HOME=${JAVA_HOME}(去掉注释) export HADOOP_HEAPSIZE=2000(去掉注释) export HADOOP_OPTS=”-Djava.security.krb5.realm=OX.AC.UK-Djava.security.krb5.kdc=kdc0.ox.ac.uk:kdc1.ox.ac.uk”(去掉注释) 6, 4个核心文件配置 6.1.配置core-site.xml——(defaultFS)指定了NameNode的主机名与端口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <? xmlversion = "1.0" encoding = "UTF-8" ?> < configuration > <!--fs.defaultFS-这是一个描述集群中NameNode结点的URI(包括协议、主机名称、端口号),集群里面的每一台机器都需要知道NameNode的地址。 DataNode结点会先在NameNode上注册,这样它们的数据才可以被使用。独立的客户端程序通过这个URI跟DataNode交互,以取得文件的块列表。--> < property > < name >fs.defaultFS</ name > < value >hdfs://localhost:8000</ value > </ property > <!--hadoop.tmp.dir是hadoop文件系统依赖的基础配置,很多路径都依赖它。 如果hdfs-site.xml中不配置namenode和datanode的存放位置,默认就放在这个路径中--> < property > < name >hadoop.tmp.dir</ name > < value >/Users/time/Documents/hadoop-2.7.3/tmp</ value > < description >Abaseforothertemporarydirectories.</ description > </ property > </ configuration > 6.2. 配置hdfs-site.xml——指定了HDFS的默认参数副本数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <? xmlversion = "1.0" encoding = "UTF-8" ?> < configuration > <!--dfs.replication-它决定着系统里面的文件块的数据备份个数。对于一个实际的应用,它应该被设为3。 少于三个的备份,可能会影响到数据的可靠性--> < property > < name >dfs.replication</ name > < value >1</ value > </ property > <!--datanaode和namenode的物理存储,如果不设置,它的值hadoop.tmp.dir--> < property > < name >dfs.namenode.name.dir</ name > < value >file:/home/hdfs/name</ value > </ property > <!--可以不设置,namenode的Web监控端口,默认是0.0.0.0:50070--> < property > < name >dfs.namenode.http-address</ name > < value >localhost:57000</ value > </ property > < property > < name >dfs.datanode.data.dir</ name > < value >file:/home/hdfs/data</ value > </ property > </ configuration > 注意这里的file 如果配置为: file:/path/a/c,则具体的路径就是: /path/a/c 如果配置为:file://path/a/c,则具体的路径就是: /a/c 6.3 mapred-site.xml配置 1 2 3 4 < property > < name >mapreduce.framework.name</ name > < value >yarn</ value > </ property > 6.4 Yarn-site.xml 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <? xmlversion = "1.0" ?> < configuration > <!--resourcemanager--> <!--clientvisitaddress--> < property > < name >yarn.resourcemanager.address</ name > < value >localhost:18040</ value > </ property > <!--ApplicationMastervisitaddress--> < property > < name >yarn.resourcemanager.scheduler.address</ name > < value >localhost:18030</ value > </ property > <!--NodeManagervisitaddress--> < property > < name >yarn.resourcemanager.resource-tracker.address</ name > < value >localhost:18025</ value > </ property > <!--webvisitaddress--> < property > < name >yarn.resourcemanager.webapp.address</ name > < value >localhost:18088</ value > </ property > <!--NodeManagersupportmapreduceservice--> < property > < name >yarn.nodemanager.aux-services</ name > < value >mapreduce_shuffle</ value > </ property > </ configuration > 7, 格式化namenode hdfs namenode-format 8, 启动hadoop 8.1sbin/start-all.sh 8.2 web测试 8.2.1 namenode-web http://localhost:50070 8.2.2resourcemanager-web http://localhost:18088 8.2.3 nodemanager-web http://localhost:8042 本文转自 zhao_xiao_long 51CTO博客,原文链接:http://blog.51cto.com/computerdragon/1939523

优秀的个人博客,低调大师

hive执行流程(1)-hive入口CliDriver类分析

在运行hive cli命令时,调用hadoop jar hive-cli-0.13.1.jar org.apache.hadoop.hive.cli.CliDriver xxxx 命令,而org.apache.hadoop.util.RunJar方法其实是封装了反射调用,最终是调用org.apache.hadoop.hive.cli.CliDriver类的main方法. CliDriver类是hive的入口类。 首先CliDriver类会通过OptionsProcessor类来parse输入的命令。比如解析-e,-s,-h等参数,然后把对应的值存放到对应的CliSessionState类的属性中,最后应用于CliDriver类中。 比如在executeDriver方法中,根据CliSessionState的属性对命令进行处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 CliDrivercli= new CliDriver(); cli.setHiveVariables(oproc.getHiveVariables()); //有变量相关的设置时 //usethespecifieddatabaseifspecified cli.processSelectDatabase(ss); //Execute-iinitfiles(alwaysinsilentmode) cli.processInitFiles(ss); //指定了-i和加载.hiverc文件 if (ss.execString!= null ){ //指定了-e时 int cmdProcessStatus=cli.processLine(ss.execString); return cmdProcessStatus; } try { //指定了-f时 if (ss.fileName!= null ){ return cli.processFile(ss.fileName); } } catch (FileNotFoundExceptione){ System.err.println( "Couldnotopeninputfileforreading.(" +e.getMessage()+ ")" ); return 3 ; } 在CliDriver类方法的调用顺序主要有下面几种 1)add xxx/set/compile/reset等命令 1 main-->run--->executeDriver---->processLine--->processCmd--->processLocalCmd--对应processor类的run方法 2)sql命令 1 main-->run--->executeDriver---->processLine--->processCmd--->processLocalCmd---->Driver类run方法 3)shell命令 1 main-->run--->executeDriver---->processLine--->processCmd 其中CliDriver类中最重要的方法是processCmd,其定义了不同的命令不同的执行方式: 具体实现: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 public int processCmd(Stringcmd){ CliSessionStatess=(CliSessionState)SessionState.get(); ss.setLastCommand(cmd); //Flushtheprintstream,soitdoesn'tincludeoutputfromthelastcommand ss.err.flush(); Stringcmd_trimmed=cmd.trim(); String[]tokens=tokenizeCmd(cmd_trimmed); int ret= 0 ; if (cmd_trimmed.toLowerCase().equals( "quit" )||cmd_trimmed.toLowerCase().equals( "exit" )){ //如果是quit或者是exit,则直接退出jvm ss.close(); System.exit( 0 ); } else if (tokens[ 0 ].equalsIgnoreCase( "source" )){ //如果是sourcexxx的情况,则按文件处理(调用processFile方法) Stringcmd_1=getFirstCmd(cmd_trimmed,tokens[ 0 ].length()); FilesourceFile= new File(cmd_1); if (!sourceFile.isFile()){ console.printError( "File:" +cmd_1+ "isnotafile." ); ret= 1 ; } else { try { this .processFile(cmd_1); } catch (IOExceptione){ console.printError( "Failedprocessingfile" +cmd_1+ "" +e.getLocalizedMessage(), stringifyException(e)); ret= 1 ; } } } else if (cmd_trimmed.startsWith( "!" )){ //以!开头的,做为shell命令执行,最终调用Runtime.getRuntime().exec(shell_cmd) Stringshell_cmd=cmd_trimmed.substring( 1 ); shell_cmd= new VariableSubstitution().substitute(ss.getConf(),shell_cmd); //这里也会进行变量替换 //shell_cmd="/bin/bash-c\'"+shell_cmd+"\'"; try { Processexecutor=Runtime.getRuntime().exec(shell_cmd); StreamPrinteroutPrinter= new StreamPrinter(executor.getInputStream(), null ,ss.out); StreamPrintererrPrinter= new StreamPrinter(executor.getErrorStream(), null ,ss.err); outPrinter.start(); errPrinter.start(); ret=executor.waitFor(); if (ret!= 0 ){ console.printError( "Commandfailedwithexitcode=" +ret); } } catch (Exceptione){ console.printError( "ExceptionraisedfromShellcommand" +e.getLocalizedMessage(), stringifyException(e)); ret= 1 ; } } else if (tokens[ 0 ].toLowerCase().equals( "list" )){ //list命令时,调用SessionState的list_resource方法 SessionState.ResourceTypet; if (tokens.length< 2 ||(t=SessionState.find_resource_type(tokens[ 1 ]))== null ){ console.printError( "Usage:list[" +StringUtils.join(SessionState.ResourceType.values(), "|" )+ "][<value>[<value>]*]" ); ret= 1 ; } else { List<String>filter= null ; if (tokens.length>= 3 ){ System.arraycopy(tokens, 2 ,tokens, 0 ,tokens.length- 2 ); filter=Arrays.asList(tokens); } Set<String>s=ss.list_resource(t,filter); if (s!= null &&!s.isEmpty()){ ss.out.println(StringUtils.join(s, "\n" )); } } } else if (ss.isRemoteMode()){ //remotemode--connectingtoremotehiveserver//如果是远程模式,即hiveserver,调用HiveClient类的execute方法 HiveClientclient=ss.getClient(); PrintStreamout=ss.out; PrintStreamerr=ss.err; try { client.execute(cmd_trimmed); List<String>results; do { results=client.fetchN(LINES_TO_FETCH); for (Stringline:results){ out.println(line); } } while (results.size()==LINES_TO_FETCH); } catch (HiveServerExceptione){ ret=e.getErrorCode(); if (ret!= 0 ){ //OKifret==0--reachedtheEOF StringerrMsg=e.getMessage(); if (errMsg== null ){ errMsg=e.toString(); } ret=e.getErrorCode(); err.println( "[HiveError]:" +errMsg); } } catch (TExceptione){ StringerrMsg=e.getMessage(); if (errMsg== null ){ errMsg=e.toString(); } ret=- 10002 ; err.println( "[ThriftError]:" +errMsg); } finally { try { client.clean(); } catch (TExceptione){ StringerrMsg=e.getMessage(); if (errMsg== null ){ errMsg=e.toString(); } err.println( "[ThriftError]:Hiveserverisnotcleanedduetothriftexception:" +errMsg); } } } else { //localmode//剩下的情况都作为local模式,比如addxxx,setxxxx,select/insertxxx/showtables/createtable,databse/usexxx等命令。 try { CommandProcessorproc=CommandProcessorFactory.get(tokens,(HiveConf)conf); //会先根据命令获取对应的CommandProcessor实现类 ret=processLocalCmd(cmd,proc,ss); //并调用processLocalCmd方法 } catch (SQLExceptione){ console.printError( "Failedprocessingcommand" +tokens[ 0 ]+ "" +e.getLocalizedMessage(), org.apache.hadoop.util.StringUtils.stringifyException(e)); ret= 1 ; } } return ret; } 而processLocalCmd方法会将CommandProcessor的实例作为参数传入,并根据不同的CommandProcessor实现类,来调用不同的类的run方法。 1 int processLocalCmd(Stringcmd,CommandProcessorproc,CliSessionStatess) 本文转自菜菜光 51CTO博客,原文链接:http://blog.51cto.com/caiguangguang/1542275,如需转载请自行联系原作者

优秀的个人博客,低调大师

spark入门知识和job任务提交流程

spark是Apache开源社区的一个分布式计算引擎,基于内存计算,所以速度要快于hadoop. 下载 地址spark.apache.org 安装 复制一台单独的虚拟机,名c 修改其ip,192.168.56.200 修改其hostname为c,hostnamectl set-hostname c 修改/etc/hosts加入对本机的解析 重启网络服务 systemctl restart network 上传spark安装文件到root目录 解压spark到/usr/local下,将其名字修改为spark 本地运行模式 使用spark-submit提交job cd /usr/local/spark ./bin/spark-submit --class org.apache.spark.examples.SparkPi ./examples/jars/spark-examples_2.11-2.1.0.jar 10000 使用spark-shell进行交互式提交 创建root下的文本文件hello.txt ./bin/spark-shell 再次连接一个terminal,用jps观察进程,会看到spark-submit进程 sc sc.textFile("/root/hello.txt") val lineRDD = sc.textFile("/root/hello.txt") lineRDD.foreach(println) 观察网页端情况 val wordRDD = lineRDD.flatMap(line => line.split(" ")) wordRDD.collect val wordCountRDD = wordRDD.map(word => (word,1)) wordCountRDD.collect val resultRDD = wordCountRDD.reduceByKey((x,y)=>x+y) resultRDD.collect val orderedRDD = resultRDD.sortByKey(false) orderedRDD.collect orderedRDD.saveAsTextFile("/root/result") 观察结果 简便写法:sc.textFile("/root/hello.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortByKey().collect 使用local模式访问hdfs数据 start-dfs.sh spark-shell执行:sc.textFile("hdfs://192.168.56.100:9000/hello.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortByKey().collect (可以把ip换成master,修改/etc/hosts) sc.textFile("hdfs://192.168.56.100:9000/hello.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortByKey().saveAsTextFile("hdfs://192.168.56.100:9000/output1") spark standalone模式 在master和所有slave上解压spark 修改master上conf/slaves文件,加入slave 修改conf/spark-env.sh,export SPARK_MASTER_HOST=master 复制spark-env.sh到每一台slave cd /usr/local/spark ./sbin/start-all.sh 在c上执行:./bin/spark-shell --master spark://192.168.56.100:7077 (也可以使用配置文件) 观察http://master:8080 spark on yarn模式 本文转自 ChinaUnicom110 51CTO博客,原文链接:http://blog.51cto.com/xingyue2011/1968175

优秀的个人博客,低调大师

移动APP 支付宝快捷支付开发流程

[代码][Java]代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 说说开发的心得吧,之前也没接触过支付宝快捷支付,不扯蛋了进入主题。 开发步骤如下 1 :在商家地址申请快捷支付 https: //b.alipay.com 在我的商家服务 申请快捷支付类,然后填写公司信息等等,提交资料进行审核 ,审核通过后会获取到 商家 PID和Key 2 :如何生成私钥,公钥 在支付宝的demo中有openssl文件夹,在bin目录下可以看到openssl.exe文件 ,打开此文件按照文档上说的,如何生成public_pey,private_key,private_psc8 支付宝生成私钥公钥的文档已经说的很清楚了。按照如下命令生成。 RSA密钥生成命令 生成RSA私钥 openssl>genrsa -out rsa_private_key.pem 1024 生成RSA公钥 openssl>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 将RSA私钥转换成PKCS8格式 openssl>pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt 生成之后,客户端android ,ios需要用到 pkcs8 ,把pkcs8的 拷贝出来粘贴到txt 文本文件,给客户端开发人员。 public_key ,android 开发需要用到,ios开发不需要。 接下来登录 支付宝商户版 https: //b.alipay.com 在我的商家服务里进行上传 刚才生成的密钥。 在合作伙伴里面上传 商户公钥,上传公钥时候请注意浏览器版本。 3 :代码集成 android ,ios server 端开发人员把支付宝提供的demo 程序可以先跑起来。 服务端我们使用的是java utf- 8 的demo 进行测试。 这里需要注意的是 retun_url和notify_url 一个是同步,一个是异步调用。在手机移动端支付retun_url 回调是用不到的,只需要用到notify_url ,这个异步回调是客户端提交订单后,支付宝服务器端异步回调应用程序服务器完成交易的一个过程,在此异步回调中可以得到订单处理状态的一些数据。并且再次可以处理应用程序内部的业务逻辑。 notify_url 如果回调不成功,请检查合作伙伴密钥管理 RAS 加密是否上传的是 商户public_key。。(此问题我们开发过程中遇到了,再次特殊提醒) 合作者身份(PID)如果notify_ur notify_url 回调多次的情况,如果发现notify_url 回调多次,请看支付宝文档 回调方法返回String success; 调试完程序之后,就可以内侧准备上线了。。 如何联系我:【万里虎】www.bravetiger.cn 【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起) 【博客】http://www.cnblogs.com/kenshinobiy/

优秀的个人博客,低调大师

SpringMVC源码分析(3)DispatcherServlet的请求处理流程

<SpringMVC源码分析(1)标签解析>:介绍了解析过程中,初始化若干组件。 <SpringMVC源码分析(2)DispatcherServlet的初始化>:初始化DispatcherServlet的多个组件。 本文继续分析DispatcherServlet解析请求的过程。 概览 ①:DispatcherServlet是springmvc中的前端控制器(front controller),负责接收request并将request转发给对应的处理组件. ②:HanlerMapping是springmvc中完成url到controller映射的组件.DispatcherServlet接收request,然后从HandlerMapping查找处理request的controller. ③:Cntroller处理request,并返回ModelAndView对象,Controller是springmvc中负责处理request的组件(类似于struts2中的Action),ModelAndView是封装结果视图的组件. ④ ⑤ ⑥:视图解析器解析ModelAndView对象并返回对应的视图给客户端. 要点 维护url和controller的映射这部分工作由DefaultAnnotationHandlerMapping.setApplicationContext的父类org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext实现。具体方法为detectHandlers protectedvoiddetectHandlers()throwsBeansException{ if(logger.isDebugEnabled()){ logger.debug("LookingforURLmappingsinapplicationcontext:"+getApplicationContext()); } String[]beanNames=(this.detectHandlersInAncestorContexts? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(),Object.class): getApplicationContext().getBeanNamesForType(Object.class)); //TakeanybeannamethatwecandetermineURLsfor. for(StringbeanName:beanNames){ String[]urls=determineUrlsForHandler(beanName); if(!ObjectUtils.isEmpty(urls)){ //URLpathsfound:Let'sconsideritahandler. registerHandler(urls,beanName); } else{ if(logger.isDebugEnabled()){ logger.debug("Rejectedbeanname'"+beanName+"':noURLpathsidentified"); } } } } 2.准确定位处理请求的具体方法(在AnnotationMethodHandlerAdapter中实现) protectedModelAndViewinvokeHandlerMethod(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler) throwsException{ ServletHandlerMethodResolvermethodResolver=getMethodResolver(handler); MethodhandlerMethod=methodResolver.resolveHandlerMethod(request);//具体实现方法的匹配 ServletHandlerMethodInvokermethodInvoker=newServletHandlerMethodInvoker(methodResolver); ServletWebRequestwebRequest=newServletWebRequest(request,response); ExtendedModelMapimplicitModel=newBindingAwareModelMap(); Objectresult=methodInvoker.invokeHandlerMethod(handlerMethod,handler,webRequest,implicitModel); ModelAndViewmav= methodInvoker.getModelAndView(handlerMethod,handler.getClass(),result,implicitModel,webRequest); methodInvoker.updateModelAttributes(handler,(mav!=null?mav.getModel():null),implicitModel,webRequest); returnmav; } 1.请求入口 @Override protectedfinalvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ proce***equest(request,response); } /** *DelegatePOSTrequeststo{@link#proce***equest}. *@see#doService */ @Override protectedfinalvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ proce***equest(request,response); } protectedfinalvoidproce***equest(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ longstartTime=System.currentTimeMillis(); ThrowablefailureCause=null; //ExposecurrentLocaleResolverandrequestasLocaleContext. LocaleContextpreviousLocaleContext=LocaleContextHolder.getLocaleContext(); LocaleContextHolder.setLocaleContext(buildLocaleContext(request),this.threadContextInheritable); //ExposecurrentRequestAttributestocurrentthread. RequestAttributespreviousRequestAttributes=RequestContextHolder.getRequestAttributes(); ServletRequestAttributesrequestAttributes=null; if(previousRequestAttributes==null||previousRequestAttributes.getClass().equals(ServletRequestAttributes.class)){ requestAttributes=newServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes,this.threadContextInheritable); } if(logger.isTraceEnabled()){ logger.trace("Boundrequestcontexttothread:"+request); } try{ doService(request,response); } catch(ServletExceptionex){ failureCause=ex; throwex; } catch(IOExceptionex){ failureCause=ex; throwex; } catch(Throwableex){ failureCause=ex; thrownewNestedServletException("Requestprocessingfailed",ex); } finally{ //Clearrequestattributesandresetthread-boundcontext. LocaleContextHolder.setLocaleContext(previousLocaleContext,this.threadContextInheritable); if(requestAttributes!=null){ RequestContextHolder.setRequestAttributes(previousRequestAttributes,this.threadContextInheritable); requestAttributes.requestCompleted(); } if(logger.isTraceEnabled()){ logger.trace("Clearedthread-boundrequestcontext:"+request); } if(failureCause!=null){ this.logger.debug("Couldnotcompleterequest",failureCause); } else{ this.logger.debug("Successfullycompletedrequest"); } if(this.publishEvents){ //Whetherornotwesucceeded,publishanevent. longprocessingTime=System.currentTimeMillis()-startTime; this.webApplicationContext.publishEvent( newServletRequestHandledEvent(this, request.getRequestURI(),request.getRemoteAddr(), request.getMethod(),getServletConfig().getServletName(), WebUtils.getSessionId(request),getUsernameForRequest(request), processingTime,failureCause)); } } } proce***equest方法主要做4项工作。 得到当前线程的LocaleContext和RequestAttributes,创建新的LocaleContext和RequestAttributes并重新绑定到当前线程。 调用子类实现的doService() 重置当前线程的LocaleContext和RequestAttributes 执行成功后,发布ServletRequestHandledEvent事件。 2.DispatcherServlet自定义的doService方法 protectedvoiddoService(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{ if(logger.isDebugEnabled()){ StringrequestUri=urlPathHelper.getRequestUri(request); logger.debug("DispatcherServletwithname'"+getServletName()+"'processing"+request.getMethod()+ "requestfor["+requestUri+"]"); } //Keepasnapshotoftherequestattributesincaseofaninclude, //tobeabletorestoretheoriginalattributesaftertheinclude. Map<String,Object>attributesSnapshot=null; if(WebUtils.isIncludeRequest(request)){ logger.debug("Takingsnapshotofrequestattributesbeforeinclude"); attributesSnapshot=newHashMap<String,Object>(); EnumerationattrNames=request.getAttributeNames(); while(attrNames.hasMoreElements()){ StringattrName=(String)attrNames.nextElement(); if(this.cleanupAfterInclude||attrName.startsWith("org.springframework.web.servlet")){ attributesSnapshot.put(attrName,request.getAttribute(attrName)); } } } //Makeframeworkobjectsavailabletohandlersandviewobjects. request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,getWebApplicationContext()); request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE,this.localeResolver); request.setAttribute(THEME_RESOLVER_ATTRIBUTE,this.themeResolver); request.setAttribute(THEME_SOURCE_ATTRIBUTE,getThemeSource()); try{ doDispatch(request,response); } finally{ //Restoretheoriginalattributesnapshot,incaseofaninclude. if(attributesSnapshot!=null){ restoreAttributesAfterInclude(request,attributesSnapshot); } } } 主要做两部分工作 如果是include请求,先保存一份request域数据的快照,doDispatch执行过后,将会用快照数据恢复。 调用doDispatch方法,完成请求转发。 3.doDispatch方法 protectedvoiddoDispatch(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{ HttpServletRequestprocessedRequest=request; HandlerExecutionChainmappedHandler=null; intinterceptorIndex=-1; try{ ModelAndViewmv; booleanerrorView=false; try{ //1.检查是否是文件上传的请求 processedRequest=checkMultipart(request); //Determinehandlerforthecurrentrequest. //2.取得处理当前请求的controller,这里也称为hanlder,处理器,第一个步骤的意义就在这里体现了. //这里并不是直接返回controller,而是返回的HandlerExecutionChain请求处理器链对象,该对象封装了handler和interceptors. mappedHandler=getHandler(processedRequest,false); if(mappedHandler==null||mappedHandler.getHandler()==null){ noHandlerFound(processedRequest,response); return; } //Determinehandleradapterforthecurrentrequest. //3.获取处理request的处理器适配器handleradapter HandlerAdapterha=getHandlerAdapter(mappedHandler.getHandler()); //Processlast-modifiedheader,ifsupportedbythehandler. Stringmethod=request.getMethod(); booleanisGet="GET".equals(method); if(isGet||"HEAD".equals(method)){ longlastModified=ha.getLastModified(request,mappedHandler.getHandler()); if(logger.isDebugEnabled()){ StringrequestUri=urlPathHelper.getRequestUri(request); logger.debug("Last-Modifiedvaluefor["+requestUri+"]is:"+lastModified); } if(newServletWebRequest(request,response).checkNotModified(lastModified)&&isGet){ return; } } //ApplypreHandlemethodsofregisteredinterceptors. //4.拦截器的预处理方法 HandlerInterceptor[]interceptors=mappedHandler.getInterceptors(); if(interceptors!=null){ for(inti=0;i<interceptors.length;i++){ HandlerInterceptorinterceptor=interceptors[i]; if(!interceptor.preHandle(processedRequest,response,mappedHandler.getHandler())){ triggerAfterCompletion(mappedHandler,interceptorIndex,processedRequest,response,null); return; } interceptorIndex=i; } } //Actuallyinvokethehandler. //5.实际的处理器处理请求,返回结果视图对象 mv=ha.handle(processedRequest,response,mappedHandler.getHandler()); //Doweneedviewnametranslation? if(mv!=null&&!mv.hasView()){ mv.setViewName(getDefaultViewName(request)); } //ApplypostHandlemethodsofregisteredinterceptors. //6.拦截器的后处理方法 if(interceptors!=null){ for(inti=interceptors.length-1;i>=0;i--){ HandlerInterceptorinterceptor=interceptors[i]; interceptor.postHandle(processedRequest,response,mappedHandler.getHandler(),mv); } } } catch(ModelAndViewDefiningExceptionex){ logger.debug("ModelAndViewDefiningExceptionencountered",ex); mv=ex.getModelAndView(); } catch(Exceptionex){ Objecthandler=(mappedHandler!=null?mappedHandler.getHandler():null); mv=processHandlerException(processedRequest,response,handler,ex); errorView=(mv!=null); } //Didthehandlerreturnaviewtorender? if(mv!=null&&!mv.wasCleared()){ render(mv,processedRequest,response); if(errorView){ WebUtils.clearErrorRequestAttributes(request); } } else{ if(logger.isDebugEnabled()){ logger.debug("NullModelAndViewreturnedtoDispatcherServletwithname'"+getServletName()+ "':assumingHandlerAdaptercompletedrequesthandling"); } } //Triggerafter-completionforsuccessfuloutcome. triggerAfterCompletion(mappedHandler,interceptorIndex,processedRequest,response,null); } catch(Exceptionex){ //Triggerafter-completionforthrownexception. triggerAfterCompletion(mappedHandler,interceptorIndex,processedRequest,response,ex); throwex; } catch(Errorerr){ ServletExceptionex=newNestedServletException("Handlerprocessingfailed",err); //Triggerafter-completionforthrownexception. triggerAfterCompletion(mappedHandler,interceptorIndex,processedRequest,response,ex); throwex; } finally{ //Cleanupanyresourcesusedbyamultipartrequest. if(processedRequest!=request){ cleanupMultipart(processedRequest); } } } 很明显这儿是SpringMVC核心。 1.根据请求的路径找到HandlerMethod(带有Method反射属性,也就是对应Controller中的方法)(DispatcherServlet.getHandler完成) 2.匹配路径对应的拦截器(DispatcherServlet.getHandler完成) 3.获得HandlerExecutionChain对象(DispatcherServlet.getHandler完成) 4.通过HandlerAdapter对象进行处理得到ModelAndView对象(HandlerAdapter.handle) 5.调用HandlerInterceptor.preHandle 6.调用HandlerInterceptor.postHandle 7. 渲染 4.总结 简单粗暴的总结下 step1-6: 获取controller step5-15 :调用controller方法 step17-20:渲染view 其他:aop方式处理拦截统一处理。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册