springMVC 怎么在方法中注入HttpServletResponse对象

我在springmvc中使用@Autowired注解可以注入HttpServletRequest对象,但是在注入HttpServletResponse之后却报错,启动直接报错

附代码如下

    @Autowired
    public HttpServletRequest request;
    
    @Autowired
    public HttpServletResponse response;

我知道可以直接在方法中把request和response当做参数传递进去的,但是我只是想知道这样为什么不行,另外想请大神们指导一下应该用哪种方法?

报错下线如下:

严重: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'neucloudOauth2Controller': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public javax.servlet.http.HttpServletResponse com.isv.spi.controllers.NeucloudOauth2Controller.response; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.servlet.http.HttpServletResponse] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    at javax.servlet.GenericServlet.init(GenericServlet.java:158)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1279)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1192)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5210)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5493)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public javax.servlet.http.HttpServletResponse com.isv.spi.controllers.NeucloudOauth2Controller.response; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.servlet.http.HttpServletResponse] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
    ... 28 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.servlet.http.HttpServletResponse] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
    ... 30 more

2016-12-01 补充问题

    @Autowired
    private DzyOauthService service;
    
    @Autowired
    private HttpServletRequest request;

DzyOauthController类需要注入上面2个参数,下面是项目启动,注入的过程日志。

2016-12-01 13:37:09,582 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating shared instance of singleton bean 'dzyOauthController'
2016-12-01 13:37:09,582 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'dzyOauthController'
2016-12-01 13:37:09,583 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Registered injected element on class [com.ucfgroup.framework.httpIntf.neucloud.dzy.controller.DzyOauthController]: AutowiredFieldElement for private com.ucfgroup.framework.httpIntf.neucloud.dzy.service.DzyOauthService com.ucfgroup.framework.httpIntf.neucloud.dzy.controller.DzyOauthController.service
2016-12-01 13:37:09,583 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Registered injected element on class [com.ucfgroup.framework.httpIntf.neucloud.dzy.controller.DzyOauthController]: AutowiredFieldElement for private javax.servlet.http.HttpServletRequest com.ucfgroup.framework.httpIntf.neucloud.dzy.controller.DzyOauthController.request


2016-12-01 13:37:09,583 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Eagerly caching bean 'dzyOauthController' to allow for resolving potential circular references


2016-12-01 13:37:09,583 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Processing injected method of bean 'dzyOauthController': AutowiredFieldElement for private com.ucfgroup.framework.httpIntf.neucloud.dzy.service.DzyOauthService com.ucfgroup.framework.httpIntf.neucloud.dzy.controller.DzyOauthController.service
2016-12-01 13:37:09,584 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'dzyOauthService'
2016-12-01 13:37:09,584 DEBUG [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] - Autowiring by type from bean name 'dzyOauthController' to bean named 'dzyOauthService'


2016-12-01 13:37:09,584 DEBUG [org.springframework.beans.factory.annotation.InjectionMetadata] - Processing injected method of bean 'dzyOauthController': AutowiredFieldElement for private javax.servlet.http.HttpServletRequest com.ucfgroup.framework.httpIntf.neucloud.dzy.controller.DzyOauthController.request
2016-12-01 13:37:09,585 DEBUG [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] - Autowiring by type from bean name 'dzyOauthController' to bean named 'com.sun.proxy.$Proxy19@14e97bf6'

2016-12-01 13:37:09,585 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Finished creating instance of bean 'dzyOauthController'

可以看出,SpringMVC为了创建以及缓存 dzyOauthController 对象,先注入了一个属性dzyOauthService,这个是正常的私有属性的注入

同时在注入HttpServletRequest的时候,注入的内容是一个代理

Autowiring by type from bean name 'dzyOauthController' to bean named 'com.sun.proxy.$Proxy19@14e97bf6'
阅读 25.9k
6 个回答

因为Request 和 Response 都是针对一次请求的

如果你只用@Autowire 或者 @Resource 注解,依赖都是在应用启动时注入的,当你应用启动的时候请求还没来呢,哪儿来的 Request和Response对象啊。
所以当你需要Request 和Response对象时,需要将其放到controller的方法的参数中,这样每次请求时,Spring MVC框架就会自动将HttpServeletRequest 或 HttpServeletResponse对象注入。

PS:Request对象表示一次请求,里面包含了本次请求的所有信息,包括Http Header和 Body,
Response对象表示对请求的响应,可以设置响应的header和body

==================================
修改
在Spring MVC中,bean的scope有singleton, prototype, request, session等级别
request级别表示每次http请求时都会创建新的对象,在spring mvc中,如果依赖了HttpServletRequest 和 HttpServletResponse对象,就会在每次请求时重新计算依赖,创建新示例

如下图所示,request和response都能取到,而且每次请求时都会创建新的实例

clipboard.png

本人小白,刚刚入住社区
我在项目中加入,是可以正常启动的,你可以试试@Autowired(required=false)让注解不进行检查,应该就会好 。
从你的报错信息来看,是没有找到对应的bean,出现这种问题,最大的可能就是没有进行bean的注入,不管是xml注入还是注解,都检查一下吧....
另外项目中貌似没有这么用的,SpringMVC就是倡导独立的request和response,这也是和struts的一点不同,具体的不同点,可以查查~
我做的项目中,对request和response 都是方法级的,每个方法独享request和response。当作参数。

错误中已经说明容器中没有request和response对象,自然无法依赖注入来实例化对象。

Servlet是服务器创建的,因此,不属于IOC管理,所以不能用自动装配,你可以在Controller里边,使用参数绑定例如Controller的一个login方法

@RequestMapping("/login")
public ModelAndView login(HttpServletRequest req) {
    // 在这里就可以直接把对应的request对象放进来了,直接可以通过req参数使用了
    // 比如req.getParameter("username") req.getAttribute("")……
}

直接这样子就可以注入了。

/**

 * 加载request数据到实体对象
 * 
 * @param request
 * @param response
 */
@ModelAttribute
public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) {
    this.request = request;
    this.response = response;
    this.session = request.getSession();
    ajaxResult = new AjaxResult();
    autotest.bingDataToEntity(request, ControllerTemplate.this);

}

因为SpringMvc是基于方法级别的,xxController是单例。在xxController类中定义成员变量是共享的,而你所需要的req/res是当前请求的,不是共享的。因此req/res需要放在方法中。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题