Controller 和 Service 中注入 HttpServletResponse 有什么差异吗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
twofox
V2EX    Java

Controller 和 Service 中注入 HttpServletResponse 有什么差异吗

  •  
  •   twofox 2022 年 4 月 6 日 2882 次点击
    这是一个创建于 1481 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目里需要导出一个文件。一开始我使用的在 Service 的实现类里面注入 response

    //serviceImpl //服务类注入 @Autowired private HttpServletResponse response; public void export(params){ // ... } 

    然后就很常规的打开流,获取文件,写入,关闭 但是无法通过项目的网关鉴权,报了一个 null 错误。

    但是如果是在 controller 里面注入,再直接传给 Service ,就可以通过鉴权。 就像这样。

    //Controller 注入 @Autowired private HttpServletResponse response; public void export(params){ //传给 service exportSevice.export(params, response); } 

    请问这两种方式注入的差别在哪?

    div class="sep20">
    18 条回复    2022-04-28 09:21:30 +08:00
    chendy
        1
    chendy  
       2022 年 4 月 6 日   1
    service 层不应该依赖 HttpServletResponse
    应该是 controller 层接 HttpServeltResponse ,serivce 层接 OutputStream

    至于鉴权啥的只能说不了解,但是这个注入方法真的有点厉害……梦回 struts2 了
    darkengine
        2
    darkengine  
       2022 年 4 月 6 日
    service 的实现类前有没有加 @ Component 注解?
    zmal
        3
    zmal  
       2022 年 4 月 6 日
    response 也能注入啊,还真不知道...
    paradoxs
        4
    paradoxs  
       2022 年 4 月 6 日
    为啥要这样注入
    shanghai1943
        5
    shanghai1943  
       2022 年 4 月 6 日
    这也能注入。。涨知识了。。
    TWorldIsNButThis
        6
    TWorldIsNButThis  
       2022 年 4 月 6 日
    为什么注入成成员变量,不是应该是方法参数吗
    不同请求过来每次都会改这个字段?
    wolfie
        7
    wolfie  
       2022 年 4 月 6 日   1
    struts2 写法,strut2 升级到 springmvc 时候,不少架构这么玩,配合 spring 默认单例 可能串会话。
    night98
        8
    night98  
       2022 年 4 月 7 日   1
    信息量太少,简单说一下,controller 是注入在 springmvc 容器里的,所以应该可以正常拿到 response ,service 层用的 spring 容器,所以拿不到,会报 null 异常,至于鉴权应该是在 request 期间鉴权的,大致应该是这样子的,
    EscYezi
        9
    EscYezi  
       2022 年 4 月 7 日 via iPhone   1
    还真没在成员变量注入过 response ,不过想了想都是单例,并发可能会有问题吧?
    twofox
        10
    twofox  
    OP
       2022 年 4 月 7 日
    @chendy 因为这是公司的项目。。同个 service 里面有类似的写法,为了保持风格一致我就这么写了。service 层确实不应依赖 Response ,我写自己的项目的时候都是传参进去的=.=


    @darkengine 加了 @Service 注解


    @TWorldIsNButThis 可能是为了少写个参数?


    @night98 很有可能,下班了试一下
    cnzjl
        11
    cnzjl  
       2022 年 4 月 7 日
    啊,我刚入行的时候就是这么注入的,比较方便
    nothingistrue
        12
    nothingistrue  
       2022 年 4 月 7 日   1
    HttpServletResponse 是绑定当前连接的有状态对象,Service 通常是无状态 Bean ,Controller 通常是( Spring MVC 就绝对是)有状态 Bean ,因此,HttpServletResponse 注入 Controller (的成员)没问题,注入 Service (的成员)会产生严重问题。

    你如果注入 Service ,那么第一个请求来了会把当前请求的 HttpServletResponse 注入单例的 Service 。单例的 Service 中的这个成员,一旦注入过就不会再重新注入了,以后所有的请求调用的 Service ,使用的都是第一个请求的 HttpServletResponse 。这个 HttpServletResponse 对象本身因为还被引用着不会被回收,但它里面引用的其他对象,会在第一个请求完成之后就销毁,于是后面就会出现 NullPointException 。


    最后说一点,exportSevice.export(params, response) 这样的方法,即把依赖对象通过方法参数传入,不是用 Spring 实现的依赖注入,但它也是依赖注入。
    twofox
        13
    twofox  
    OP
       2022 年 4 月 7 日
    @nothingistrue 那正确的写法呢?
    exportSevice.export(params, response.getOutputStream())
    nothingistrue
        14
    nothingistrue  
       2022 年 4 月 7 日   1
    你的第二次使用已经正确了:注入到 Controller ,再传递给 Service 。Controller 是非单例的有状态 Bean ,可以注入 HttpServletResponse 。 @twofox

    其实对于 HttpServletResponse 这种跟当前请求绑定的对象,最好全程通过方法参数注入,不要将他注入到类的成员变量上。Spring MVC 中,如果把 HttpServletResponse 作为 Controller 的方法的参数,不需要加 Autowired 它都是自动注入的。
    threee333
        15
    threee333  
       2022 年 4 月 7 日
    @nothingistrue #14 「 Controller 是非单例的有状态 Bean 」?不对吧,Controller 默认应该也是单例的。
    nothingistrue
        16
    nothingistrue  
       2022 年 4 月 8 日
    @codergrowing #15 可能我记错了,不过 Spring Boot 之后,Spring MVC 部分推荐的都是通过方法参数注入,已经基本不用成员变量注入了,这种注入单例非单例都没区别。一般来说,从 Struts2 之后,控制器部分都是单例的,可能 Spring MVC 发现没有成员变量注入之后会自动优化成单例模式。
    twofox
        17
    twofox  
    OP
       2022 年 4 月 8 日
    @nothingistrue 感谢答疑!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1651 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 65ms UTC 6:18 PVG 00:18 LAX 09:18 JFK 12:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86