一、SpringMVC基础入门,创建一个HelloWorld程序
二、配置解析
三、SpringMVC常用注解
四、自动匹配参数
五、自动装箱
六、使用InitBinder来处理Date类型的参数
七、向前台传递参数
八、使用Ajax调用
九、在Controller中使用redirect方式处理请求
十、文件上传
十一、使用@RequestParam注解指定参数的name
十二、RESTFul风格的SringMVC
十三、返回json格式的字符串
十四、异常的处理
十五、设置一个自定义拦截器
十六、表单的验证(使用Hibernate-validate)及国际化
十七、压轴大戏--整合SpringIOC和SpringMVC
十八、SpringMVC详细运行流程图
十九、SpringMVC运行原理
二十、SpringMVC与struts2的区别
java.nio全称java non-blocking IO,是指jdk1.4 及以上版本里提供的新api(New IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。 Sun 官方标榜的特性如下: 为所有的原始类型提供(Buffer)缓存支持。字符集编码解码解决方案。 Channel :一个新的原始I/O 抽象。 支持锁和内存映射文件的文件访问接口。 提供多路(non-bloking) 非阻塞式的高伸缩性网络I/O 。
View DetailsJava消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。 点对点与发布订阅最初是由JMS定义的。这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费(多订阅) 1、定义 JMS规范目前支持两种消息模型:点对点(point to point, queue)和发布/订阅(publish/subscribe,topic)。 1.1、点对点:Queue,不可重复消费 消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。 消息被消费以后,queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。 1.2、发布/订阅:Topic,可以重复消费 消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有订阅者消费。 支持订阅组的发布订阅模式: 发布订阅模式下,当发布者消息量很大时,显然单个订阅者的处理能力是不足的。实际上现实场景中是多个订阅者节点组成一个订阅组负载均衡消费topic消息即分组订阅,这样订阅者很容易实现消费能力线性扩展。可以看成是一个topic下有多个Queue,每个Queue是点对点的方式,Queue之间是发布订阅方式。 2、区别 2.1、点对点模式 生产者发送一条消息到queue,一个queue可以有很多消费者,但是一个消息只能被一个消费者接受,当没有消费者可用时,这个消息会被保存直到有 一个可用的消费者,所以Queue实现了一个可靠的负载均衡。 2.2、发布订阅模式 发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息。topic实现了发布和订阅,当你发布一个消息,所有订阅这个topic的服务都能得到这个消息,所以从1到N个订阅者都能得到这个消息的拷贝。 3、流行模型比较 传统企业型消息队列ActiveMQ遵循了JMS规范,实现了点对点和发布订阅模型,但其他流行的消息队列RabbitMQ、Kafka并没有遵循JMS规范。 3.1、RabbitMQ RabbitMQ实现了AQMP协议,AQMP协议定义了消息路由规则和方式。生产端通过路由规则发送消息到不同queue,消费端根据queue名称消费消息。 RabbitMQ既支持内存队列也支持持久化队列,消费端为推模型,消费状态和订阅关系由服务端负责维护,消息消费完后立即删除,不保留历史消息。 (1)点对点 生产端发送一条消息通过路由投递到Queue,只有一个消费者能消费到。 (2)多订阅 当RabbitMQ需要支持多订阅时,发布者发送的消息通过路由同时写到多个Queue,不同订阅组消费不同的Queue。所以支持多订阅时,消息会多个拷贝。 3.2、Kafka Kafka只支持消息持久化,消费端为拉模型,消费状态和订阅关系由客户端端负责维护,消息消费完后不会立即删除,会保留历史消息。因此支持多订阅时,消息只会存储一份就可以了。但是可能产生重复消费的情况。 (1)点对点&多订阅 发布者生产一条消息到topic中,不同订阅组消费此消息。 from:http://blog.csdn.net/heyutao007/article/details/50131089
View DetailsNeo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。 Neo4j因其嵌入式、高性能、轻量级等优势,越来越受到关注.
View Details请看解决方案: 1. 修改maven的settings.xml文件。 添加以下行,jdk版本改为自己需要的版本:
1 2 3 4 5 6 7 8 9 10 11 12 |
<profile> <id>jdk-1.7</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.7</jdk> </activation> <properties> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion> </properties> </profile> |
2. 在eclipse中检查配置文件是否被引用到,之前我的user settting使用的位置不对。 然后update setttings。 3. 最后选择创建的项目,更新项目后,引用的jdk版本自动刷新。 from:http://www.cnblogs.com/30go/p/7154298.html
View Details问题描述:eclipse加载新的项目后报一个错误,具体描述如下: Description Resource PathLocation Type Java compiler level does notmatch the version of the installed Java project facet.webattemp Unknown FacetedProject Problem (Java Version Mismatch) 问题分析: java版本不匹配:Facted Project 中的Java 版本设定与项目的Java 版本设定不一致。 问题解决: 在当前项目上点右键,属性--Project Facets中,配置编译版本与java compiler的版本一致。 1、选中项目后按下alt+enter组合键或者右键Project | Properties | Java Compiler(type filter text输入compiler可快速定位),如下图所示: 2、修改Project Facets的Java值,使之和Compiler compliance level相同:打开方式参考1,如下图: 总结: 刚开始用的是eclipse比较老的一个版本,常用的文件定位的插件装上就是识别不出来,换了一个高版本的eclipse加载项目后就报出上面的错误,因为是第一次见到这个错误,以为是用的这个项目不支持高版本的eclipse呢,头说不行就用那个老版本得了,不要在这个上浪费时间,可是提高班培养出来的习惯,这样感觉就是不爽,还是想查一下再说,上网一查,这样的问题很多,当然很快就找到了解决的办法,工欲善其事,必先利其器,有了好的工具开发的时候心情好多了,自然效率也就提高了。 参考:http://blog.163.com/luckcq@yeah/blog/static/171747707201172223546805/ from:http://blog.163.com/lfsyhuangaigang@126/blog/static/774366702012913113253907/
View DetailsStruts2、SpringMVC、Servlet(Jsp)性能对比 测试 。 Servlet的性能应该是最好的,可以做为参考基准,其它测试都要向它看齐,参照它。 做为一个程序员,对于各个框架的性能要有一个基本的认知,便于选型时做出正确的决策。 在测试中发现了什么也不要大喊大叫,因为这些都是Java程序员的基础知识。 人人都要了解。 ————————————————————————————— 建议先阅读《你想建设一个能承受500万PV/每天的网站吗? 》一文,了解一些测试的基本概念。在测试开始前就有一个性能好与坏的标准。再用这个标准来检验你程序。 ————————————————————————————— 测试环境说明: 服务器: 4G内存,至强3.0 (4核超线程)CPU,windows 2003 测试机:笔记本 2G内存,p8600 双核CPU,windows XP 网络:100Mb局域网 测试软件: Jmeter 2.3.4 分配了512M内存 tomcat 6 默认内存大小 ————————————————————————————— 测试配置如下图: 其实jmeter还是很弱的,我打开"集合点(synchronizing Timer)","察看结果树","用表格查看结果"中的任何一个都会导致测试结果中的性能下降和小部分请求的响应出错(可能是线程数太多了),所以禁用了。只启用了cookie管理器。 ————————————————————————————— Tomcat6.0 配置文件的说明 ,做测试之前是要整清楚的。 默认的Server.xml中如下 Xml代码 <Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" /> enableLookups 是否允许DNS查询,当web应用程序要通过域名服务器查找机器名转换为IP地址时。会使用DNS查询,需要占用网络,延长较长 maxThreads Tomcat可创建的最大的线程数,每一个请求须要一个线程来处理,原来的150太小了,我们测试时并发会超过他的。 acceptCount 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,就是被排队的请求数,超过这个数的请求将拒绝连接。 connnectionTimeout 网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为20000毫秒。 minSpareThreads Tomcat初始化时创建的线程数 maxSpareThreads 一旦创建的线程中空闲线程超过这个值,Tomcat就会关闭不再需要的socket线程。 注意:maxThreads 设置为500 ,也就是Tomcat最多同时使用500个线程处理500个并发(服务器CPU不错,500没问题),不要发生 排队等待的情况以免影响测试成绩, 为下面的压力测试做好准备。 ———————————测试开始了——————————————- 测试时服务器CPU使用率 10% 测试时测试机CPU使用率 100%(测试机不行啊,主要是 Jmeter的性能一般,又吃内存,测试机p8600 双核CPU还是很强的 ) 每次测试CPU都这样,就统一写这里了。 测试1:JSP页面--2213个请求/秒 100并发,循环100次,共10000个请求,请求一个大小3.34KB的jsp页面。 测试2:JSP页面--1889个请求/秒 100并发,循环100次,共10000个请求,请求一个servlet总控制器,验证权限后(很简单),new一个Action,再转发到一个大小3.34KB的jsp页面。 测试3:HTML页面--2607个请求/秒 100并发,循环100次,共10000个请求,请求一个3.2KB的html页面。 测试4: HTML页面-- 833个请求/秒 100并发,循环100次,共10000个请求,请求一个13.4KB的html页面。与上面比是只是文件大了一些,把网卡跑满了 ,网卡成为了性能瓶颈,RPS降了不少!! 测试5: Spring MVC 2012个请求/秒 100并发,循环100次,共10000个请求,请求一个spring3 MVC的action,再转发到一个0.8K的JSP,其内容是简单的html […]
View Details你想建设一个能承受500万PV/每天的网站吗? 500万PV是什么概念?服务器每秒要处理多少个请求才能应对?如果计算呢? PV是什么: PV是page view的简写。PV是指页面的访问次数,每打开或刷新一次页面,就算做一个pv。 计算模型: 每台服务器每秒处理请求的数量=((80%*总PV量)/(24小时*60分*60秒*40%)) / 服务器数量 。 其中关键的参数是80%、40%。表示一天中有80%的请求发生在一天的40%的时间内。24小时的40%是9.6小时,有80%的请求发生一天的9.6个小时当中(很适合互联网的应用,白天请求多,晚上请求少)。 简单计算的结果: ((80%*500万)/(24小时*60分*60秒*40%))/1 = 115.7个请求/秒 ((80%*100万)/(24小时*60分*60秒*40%))/1 = 23.1个请求/秒 初步结论: 现在我们在做压力测试时,就有了标准,如果你的服务器一秒能处理115.7个请求,就可以承受500万PV/每天。如果你的服务器一秒能处理23.1个请求,就可以承受100万PV/每天。 留足余量: 以上请求数量是均匀的分布在白天的9.6个小时中,但实际情况并不会这么均匀的分布,会有高峰有低谷。为了应对高峰时段,应该留一些余地,最少也要x2倍,x3倍也不为过。 115.7个请求/秒 *2倍=231.4个请求/秒 115.7个请求/秒 *3倍=347.1个请求/秒 23.1个请求/秒 *2倍=46.2个请求/秒 23.1个请求/秒 *3倍=69.3个请求/秒 最终结论: 如果你的服务器一秒能处理231.4--347.1个请求/秒,就可以应对平均500万PV/每天。 如果你的服务器一秒能处理46.2--69.3个请求,就可以应对平均100万PV/每天。 说明: 这里说明每秒N个请求,就是QPS。因为我关心的是应用程序处理业务的能力。 实际经验: 1、根据实际经验,采用两台常规配置的机架式服务器,配置是很常见的配置,例如一个4核CPU+4G内存+服务器SAS硬盘。 2、个人武断的认为在服务器CPU领域Intel的CPU要优于AMD的CPU,有反对的就反对吧,我都说我武断了(请看CPU性能比较),不要太相信AMD的广告,比较CPU性能简单办法就是比价格,不要比频率与核心数,价格相差不多的性能也相差不多。 3、硬盘的性能很重要,由其是数据库服务器。一般的服务器都配1.5万转的SAS硬盘,高级一点的可以配SSD固态硬盘,性能会更好。最最最最重要的指标是“随机读写性能”而不是“顺序读写性能”。(本例还是配置最常见的1.5万转的SAS硬盘吧) 4、一台服务器跑Tomcat运行j2ee程序,一台服务器跑MySql数据库,程序写的中等水平(这个真的不好量化),是论坛类型的应用(总有回帖,不太容易做缓存,也无法静态化)。 5、以上软硬件情况下,是可以承受100万PV/每天的。(已留有余量应对突然的访问高峰) 注意机房的网络带宽: 有人说以上条件我都满足了,但实际性能还是达不到目标。这时请注意你对外的网络的带宽,在国内服务器便宜但带宽很贵,很可能你在机房是与大家共享一条100M的光纤,实际每个人可分到2M左右带宽。再好一点5M,再好一点双线机房10M独享,这已经很贵了(北京价格)。 一天总流量:每个页面20k字节*100万个页面/1024=19531M字节=19G字节, 19531M/9.6小时=2034M/小时=578K字节/s 如果请求是均匀分布的,需要5M(640K字节)带宽(5Mb=640KB 注意大小写,b是位,B是字节,差了8倍),但所有请求不可能是均匀分布的,当有高峰时5M带宽一定不够,X2倍就是10M带宽。10M带宽基本可以满足要求。 以上是假设每个页面20k字节,基本不包含图片,要是包含图片就更大了,10M带宽也不能满足要求了。你自已计算吧。 (全文完) 附:性能测试基本概念 ————————————————————————————— 基本概念: Throughput(吞吐量):按照常规理解网络吞吐量表示在单位时间内通过网卡数据量之和,其中即包括本机网卡发送出去的数据量也包括本机网卡接收到的数据量。 一个100Mb(位)的双工网卡,最大发送数据的速度是12.5M字节/s , 最大接收数据的速度是12.5M字节/s, 可以 同时 收发 数据。 并发用户数:是同时执行操作的用户(线程数)。 响应时间:从请求发出到收到响应花费的时间 。 QPS – Queries Per Second 每秒处理的查询数(如果是数据库,就相当于读取) TPS – Transactions Per Second 每秒处理的事务数(如果是数据库,就相当于写入、修改) IOPS,每秒磁盘进行的I/O操作次数 例如对某个数据库测试,分开两次测QPS与TPS。 QPS(读取)值总是高于TPS(写、改),并且有倍率关系,因为: 1、数据库对查询可能有缓存。 2、机械硬盘或SSD硬盘的读就是比写快。 ————————————————————————————— JMeter测试参数说明: […]
View Details目录 一、前言 二、spring mvc 核心类与接口 三、spring mvc 核心流程图 四、spring mvc DispatcherServlet说明 五、spring mvc 父子上下文的说明 六、springMVC-mvc.xml 配置文件片段讲解 七、spring mvc 如何访问到静态的文件,如jpg,js,css 八、spring mvc 请求如何映射到具体的Action中的方法 九、 spring mvc 中的拦截器: 十、 spring mvc 如何使用拦截器 十一、 spring mvc 如何实现全局的异常处理 十二、 spring mvc 如何把全局异常记录到日志中 十三、 如何给spring3 MVC中的Action做JUnit单元测试 十四、 spring mvc 转发与重定向 (带参数重定向) 十五、 spring mvc 处理ajax请求 十六、 spring mvc 关于写几个配置文件的说明 十七、 spring mvc 如何取得Spring管理的bean 十八、 spring mvc 多视图控制器 十九、 <mvc:annotation-driven /> 到底做了什么工作 二十、 本文中springMVC.xml配置文件是核心,这里给一个下载地址 说明:本作者是文章的原创作者,转载请注明出处:本文地址:http://elf8848.iteye.com/blog/875830 一、前言: 为开发团队选择一款优秀的MVC框架是件难事儿,在众多可行的方案中决择需要很高的经验和水平。你的一个决定会影响团队未来的几年。要考虑方面太多: 1、简单易用,以提高开发效率。使小部分的精力在框架上,大部分的精力放在业务上。 2、性能优秀,这是一个最能吸引眼球的话题。 3、尽量使用大众的框架(避免使用小众的、私有的框架),新招聘来的开发人员有一些这方面技术积累,减低人员流动再适应的影响。 如果你还在为这件事件发愁,本文最适合你了。选择Spring MVC吧。 Spring MVC是当前最优秀的MVC框架,自从Spring 2.5版本发布后,由于支持注解配置,易用性有了大幅度的提高。Spring 3.0更加完善,实现了对Struts 2的超越。现在越来越多的开发团队选择了Spring MVC。 Struts2也是非常优秀的MVC构架,优点非常多比如良好的结构,拦截器的思想,丰富的功能。但这里想说的是缺点,Struts2由于采用了值栈、OGNL表达式、struts2标签库等,会导致应用的性能下降,应避免使用这些功能。而Struts2的多层拦截器、多实例action性能都很好。可以参考我写的一篇关于Spring MVC与Struts2与Servlet比较的文章《Struts2、SpringMVC、Servlet(Jsp)性能对比 测试》 Spring3 MVC的优点: 1、Spring3 MVC使用简单,学习成本低。学习难度小于Struts2,Struts2用不上的多余功能太多。呵呵,当然这不是决定因素。 2、Spring3 MVC很容易就可以写出性能优秀的程序,Struts2要处处小心才可以写出性能优秀的程序(指MVC部分) 3、Spring3 MVC的灵活是你无法想像的,Spring框架的扩展性有口皆碑,Spring3 MVC当然也不会落后,不会因使用了MVC框架而感到有任何的限制。 Struts2的众多优点: 1、老牌的知名框架,从Struts1起积累了大量用户群体。技术文档丰富。 2、其它方面略… (呵呵,是不是不公平?) Spring的官方下载网址是:http://www.springsource.org/download […]
View Details平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。 spring有多种依赖注入的形式,下面仅介绍spring通过xml进行IOC配置的方式: Set注入 这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口): Java代码 package com.bless.springdemo.action; public class SpringAction { //注入对象springDao private SpringDao springDao; //一定要写被注入对象的set方法 public void setSpringDao(SpringDao springDao) { this.springDao = springDao; } public void ok(){ springDao.ok(); } } 随后编写spring的xml文件,<bean>中的name属性是class属性的一个别名,class属性指类的全名,因为在SpringAction中有一个公共属性Springdao,所以要在<bean>标签中创建一个<property>标签指定SpringDao。<property>标签中的name就是SpringAction类中的SpringDao属性名,ref指下面<bean name="springDao"…>,这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction的setSpringDao方法将SpringDao注入: Java代码 <!--配置bean,配置后该类由spring管理--> <bean name="springAction" class="com.bless.springdemo.action.SpringAction"> <!--(1)依赖注入,配置当前类中相应的属性--> <property name="springDao" ref="springDao"></property> </bean> <bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean> 构造器注入 这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来: Java代码 public class SpringAction { //注入对象springDao private SpringDao springDao; private User user; public SpringAction(SpringDao springDao,User user){ this.springDao = springDao; this.user = user; System.out.println("构造方法调用springDao和user"); } public void save(){ user.setName("卡卡"); springDao.save(user); } } 在XML文件中同样不用<property>的形式,而是使用<constructor-arg>标签,ref属性同样指向其它<bean>标签的name属性: Xml代码 <!--配置bean,配置后该类由spring管理--> <bean name="springAction" class="com.bless.springdemo.action.SpringAction"> <!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置--> <constructor-arg ref="springDao"></constructor-arg> <constructor-arg ref="user"></constructor-arg> </bean> <bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean> <bean name="user" class="com.bless.springdemo.vo.User"></bean> 解决构造方法参数的不确定性,你可能会遇到构造方法传入的两参数都是同类型的,为了分清哪个该赋对应值,则需要进行一些小处理: 下面是设置index,就是参数位置: Xml代码 <bean name="springAction" class="com.bless.springdemo.action.SpringAction"> <constructor-arg index="0" ref="springDao"></constructor-arg> <constructor-arg index="1" ref="user"></constructor-arg> </bean> 另一种是设置参数类型: Xml代码 <constructor-arg type="java.lang.String" ref=""/> 静态工厂的方法注入 静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取: Java代码 package com.bless.springdemo.factory; import com.bless.springdemo.dao.FactoryDao; import com.bless.springdemo.dao.impl.FactoryDaoImpl; import com.bless.springdemo.dao.impl.StaticFacotryDaoImpl; public class DaoFactory { //静态工厂 public static final FactoryDao getStaticFactoryDaoImpl(){ return new StaticFacotryDaoImpl(); } } 同样看关键类,这里我需要注入一个FactoryDao对象,这里看起来跟第一种注入一模一样,但是看随后的xml会发现有很大差别: Java代码 […]
View Details