为什么所有的请求都会发送给springmvc获取请求url处理

springMVC一个Controller处理所有用户请求的并发问题 -
- ITeye博客
博客分类:
有状态和无状态的对象基本概念: 有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。一般是prototype scope。无状态对象(Stateless Bean),就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。一般是singleton scope。
如Struts2中的Action,假如内部有实例变量User,当调用新增用户方法时,user是用来保存数据,那么此action是有状态对象。多个线程同时访问此action时 会造成user变量的不一致。所以action的scope要设计成prototype,或者,User类放到threadLocal里来保持多个线程不会造成User变量的乱串(此种场景没必要放到threadLocal内)。
而Service内部一般只有dao实例变量 如userDao, 因为userDao是无状态的对象(内部无实例变量且不能保存数据),所以service也是无状态的对象。
XxxAction{
   // 由于多线程环境下,user是引用对象,是非线程安全的
  public
  ......
XxxService {
  // 虽然有billDao属性,但billDao是没有状态信息的,是Stateless Bean.
  BillDao billD
  ......
对于那些会以多线程运行的单例类
局部变量不会受多线程影响,成员变量会受到多线程影响。
多个线程调用同一个对象的同一个方法: 如果方法里无局部变量,那么不受任何影响;如果方法里有局部变量,只有读操作,不受影响;存在写操作,考虑多线程影响值;
例如Web应用中的Servlet,每个方法中对局部变量的操作都是在线程自己独立的内存区域内完成的,所以是线程安全的。 对于成员变量的操作,可以使用ThreadLocal来保证线程安全。
springMVC中,一般Controller、service、DAO层的scope均是singleton;
每个请求都是单独的线程,即使同时访问同一个Controller对象,因为并没有修改Controller对象,相当于针对Controller对象而言,只是读操作,没有写操作,不需要做同步处理。
Service层、Dao层用默认singleton就行,虽然Service类也有dao这样的属性,但dao这些类都是没有状态信息的,也就是 相当于不变(immutable)类,所以不影响。
Struts2中的Action因为会有User、BizEntity这样的实例对象,是有状态信息 的,在多线程环境下是不安全的,所以Struts2默认的实现是Prototype模式。在Spring中,Struts2的Action中scope 要配成prototype作用域。
Spring并发访问的线程安全性问题
由于Spring MVC默认是Singleton的,所以会产生一个潜在的安全隐患。根本核心是instance变量保持状态的问题。这意味着每个request过来,系统都会用原有的instance去处理,这样导致了两个结果:一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程同时调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。当然大多数情况下,我们根本不需要考虑线程安全的问题,比如dao,service等,除非在bean中声明了实例变量。因此,我们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。 如:
publicclassControllerextendsAbstractCommandController{
protectedModelAndView handle(HttpServletRequest request,HttpServletResponse response,
Object command,BindException errors)throwsException{
company =................;
protectedCompany company;
在这里有声明一个变量company,这里就存在并发线程安全的问题。如果控制器是使用单例形式,且controller中有一个私有的变量a,所有请求到同一个controller时,使用的a变量是共用的,即若是某个请求中修改了这个变量a,则,在别的请求中能够读到这个修改的内容。。有几种解决方法:1、在控制器中不使用实例变量2、将控制器的作用域从单例改为原型,即在spring配置文件Controller中声明 scope="prototype",每次都创建新的controller3、在Controller中使用ThreadLocal变量这几种做法有好有坏,第一种,需要开发人员拥有较高的编程水平与思想意识,在编码过程中力求避免出现这种BUG,而第二种则是容器自动的对每个请求产生一个实例,由JVM进行垃圾回收,因此做到了线程安全。使用第一种方式的好处是实例对象只有一个,所有的请求都调用该实例对象,速度和性能上要优于第二种,不好的地方,就是需要程序员自己去控制实例变量的状态保持问题。第二种由于每次请求都创建一个实例,所以会消耗较多的内存空间。所以在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的
浏览 10737
浏览: 103353 次
来自: 杭州
楼主明显的误导人啊
局部变量,成员变量没搞清楚呢
如果方法里无局部变量,那么不受任何影响;如果方法里有局部变量, ...
然后这是jsp的代码,谢谢var userEm = new E ...
这是servlet的方法,但是一直提交不过去,能帮我看下么pu ...下次自动登录
现在的位置:
& 综合 & 正文
SpringMVC @RequestBody 处理ajax请求
1.问题描述
最近在和前台调试代码时发现了如下的问题:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unexpected character ('c' (code 99)): expected a valid value
(number, String, array, object, 'true', 'false' or 'null')。
前台是发的ajax请求,数据是一个json对象。
后台发现这个错一般是传递的json数据格式有问题。
2.将对象传到Java端
在SpringMVC环境中, @RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。然而在ajax请求往往传的都是Json对象,后来发现用JSON.stringify(data)的方式就能将对象变成字符串。同时ajax请求的时候也要指定dataType:
"json",contentType:"application/json"这样就可以轻易的将一个对象传到Java端,使用@RequestBody即可绑定对象
3.如何将List对象传到Java端:
&script type="text/javascript"&
$(document).ready(function(){
var saveDataAry=[];
var data1={"userName":"test","address":"gz"};
var data2={"userName":"ququ","address":"gr"};
saveDataAry.push(data1);
saveDataAry.push(data2);
type:"POST",
url:"user/saveUser",
dataType:"json",
contentType:"application/json",
data:JSON.stringify(saveData),
success:function(data){
JSON.stringify() : 将对象转换成json字符串。
JSON.parse(): 将json字符串转换成json对象。
@RequestMapping(value = "saveUser", method = {RequestMethod.POST }})
@ResponseBody
public void saveUser(@RequestBody List&User& users) {
userService.batchSave(users);
这样是不可以的。因为spring MVC不会自动转换为List&User&对象。传到后台后,List中是LinkedHashMap类型。
但是使用数组就可以接受了User[] ,如下:
@RequestMapping(value = "saveUser", method = {RequestMethod.POST }})
@ResponseBody
public void saveUser(@RequestBody User[] users) {
userService.batchSave(users);
&&&&推荐文章:
【上篇】【下篇】18:51 提问
关于Ajax发送请求的问题
发送ajax请求,响应406
后台用springMVC3.0,注解配置@ReponseBody返回json数据。
前台用了Extjs,刚开始用火狐浏览器测试,一直都OK。今天突然想起来用IE来测,
结果就出现了这个问题,然后又用GOOGLE,也是如此。
后来写了个测试页面,用jquery来发,发现也是一样的情况。火狐ok,IE和GOOELE:406
之后在controller里,取消@ResponseBody注解,
直接用response设置setcontentType为json,
然后 response.getWrite().write()就OK了。
但是…………项目已经开发了一半了,这样去改要出人命的。
现在完全没方向,到底是浏览器兼容问题,还是springMVC配置问题呢?
求大神 伸大腿呀……………………
按赞数排序
406状态是服务器设置的,和ajax没关系。应该是你服务器做了请求头的判断,ie或者firefox有些请求头不一样,所以响应不一样
其他相关推荐
其他相似问题本帖子已过去太久远了,不再提供回复功能。SpringMvc(1)
1:首先客户端发送一个http请求,web服务器接受这个请求,然后web容器交给DispatcherSevlet处理。
2:DispatcherSevlet将负责将请求分发。DispatcherSevlet可以认为是spring提供的前端控制器,所有的请求都要经过他来进行统一的分发。
3:在DispatcherSevlet将请求分发给spring
controller之前,需要借助于spring提供的HandleMapping定位到具体的controller。(HandleMapping是这样的一种对象,他能够完成客户请求和controller之间的映射。在structs中,这种映射是通过struts-config.xml文件完成的。spring为controller提供了若干实现,例如:BeanNameUrlHandlerMapping有,SimpleUrlHandlerMapping,CommonsPathMapHandlerMapping。)
controller将处理来自DispatcherSevlet的请求。spring的controller类似于structs的action。能够接受HttpServletRequest和HttpServletResponse。spring为controller提供了若干实现类,由于controller要为并发用户处理上述请求,因此实现controller接口时,必须保证线程安全并且可重用。controller将处理用户请求,这和structs中的action是一致的。
5:一旦controller处理完用户请求,则返回ModelAndView对象给DispatcherSevlet前端控制。ModelAndView包含了模型(model)和视图(view)。从宏观角度来看,DispatcherSevlet是整个web应用的控制器。从微观来看,controller是单个http请求的控制器。而ModelAndView是http请求过程中返回的模型和视图。
6:ModelAndView中包含了视图逻辑名与模型数据信息。DispatcherSevlet通过ViewResolver完成逻辑视图名到真实视图对象的解析工作。
7:当得到真实对象的view,DispatcherServlet就使用这个View对象对ModelAndView中的模型数据进行视图渲染。然后将渲染后的结果返回给客户。
文章转载:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1516次
排名:千里之外
原创:19篇
转载:13篇
(2)(32)(2)(2)

我要回帖

更多关于 spring mvc 请求转发 的文章

 

随机推荐