英文:
How to set cacheControlMappings in WebContentInterceptor in Spring 5 Xml
问题
以下是您要翻译的内容:
我想在Spring MVC中为一些URL添加cache-control指令(同时设置public和max-age秒),我希望只通过applicationContext.xml进行这些更改。
我尝试设置org.springframework.web.servlet.mvc.WebContentInterceptor
的map属性cacheControlMappings
,但唯一的问题是这个类的设计没有为该属性提供setter方法。作为解决方法,我正在使用org.springframework.beans.factory.config.MethodInvokingBean
来调用addCacheMapping
方法。
我的spring-mvc-config.xml中的配置如下 -
我创建了一个名为CacheControl
的bean,如下所示,并且我通过调试验证了这个bean会在应用程序上下文中成功创建,并且填充了适当的值。
<bean id="cacheControlFactory" class="org.springframework.http.CacheControl" factory-method="maxAge">
<constructor-arg index="0" value="3600"/>
<constructor-arg index="1">
<value type="java.util.concurrent.TimeUnit">SECONDS</value>
</constructor-arg>
</bean>
<bean id="myCacheControl" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref bean="cacheControlFactory"/>
</property>
<property name="targetMethod">
<value>cachePublic</value>
</property>
</bean>
然后,我希望调用WebContentInterceptor
的public void addCacheMapping(CacheControl cacheControl, String... paths)
方法,这将向mapcacheControlMappings
添加条目。
我验证过以编程方式调用此方法效果很好,所以如果我从XML中调用它应该也没问题,对吧?但是,我正在尝试做相同的事情,如下所示,但是对我来说不起作用,最终的map中没有添加任何条目。
<bean class="org.springframework.beans.factory.config.MethodInvokingBean">
<property name="targetObject">
<ref bean="webContentInterceptor"/>
</property>
<property name="targetMethod">
<value>addCacheMapping</value>
</property>
<property name="arguments">
<list>
<ref bean="myCacheControl" />
<value>/home</value>
<value>/dp/**</value>
<value>/**/b/*</value>
</list>
</property>
</bean>
为什么上述使用MethodInvokingBean
的调用不起作用?我是否在设置参数方面做错了什么?可变参数是否需要不同的处理?我在服务器启动期间也没有看到任何错误被抛出。
另外,我知道这个SO线程(https://stackoverflow.com/questions/46159288/how-to-set-cache-control-private-with-applicationcontext-xml-in-spring-4-2-or-l),接受的答案提到在XML本身中没有办法做到这一点。我想通过尝试实现上述解决方案来重新确认是否正确,但它不起作用,但我不知道为什么。
英文:
I want to add cache-control directive (set both public and max-age seconds) for a couple of URLs in Spring MVC and I want to do those changes via applicationContext.xml only.
I am trying to set the map property cacheControlMappings
of org.springframework.web.servlet.mvc.WebContentInterceptor
, but the only problem is the design of the class which has no setter method for the property. As a workaround, I am invoking the addCacheMapping
method using the org.springframework.beans.factory.config.MethodInvokingBean
.
My configuration in spring-mvc-config.xml is as follows -
I am creating a CacheControl
bean as follows, and I verified by debugging that this bean gets created successfully with appropriate values populated in the application context.
<bean id="cacheControlFactory" class="org.springframework.http.CacheControl" factory-method="maxAge">
<constructor-arg index="0" value="3600"/>
<constructor-arg index="1">
<value type="java.util.concurrent.TimeUnit">SECONDS</value>
</constructor-arg>
</bean>
<bean id="myCacheControl" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref bean="cacheControlFactory"/>
</property>
<property name="targetMethod">
<value>cachePublic</value>
</property>
</bean>
Then I wish to invoke this method - public void addCacheMapping(CacheControl cacheControl, String... paths)
of WebContentInterceptor
which will add entries to the map cacheControlMappings
.
I verified that calling this method programmatically works great, so it should work fine if I invoke it from the XML right? But I am trying to do the same, as shown below, but this does not work for me, and I get zero entries added to the final map.
<bean class="org.springframework.beans.factory.config.MethodInvokingBean">
<property name="targetObject">
<ref bean="webContentInterceptor"/>
</property>
<property name="targetMethod">
<value>addCacheMapping</value>
</property>
<property name="arguments">
<list>
<ref bean="myCacheControl" />
<value>/home</value>
<value>/dp/**</value>
<value>/**/b/*</value>
</list>
</property>
</bean>
Why does the above invocation with MethodInvokingBean
not work? Am I setting the arguments wrong in any way? Do the varargs need a different handling? I don't see any errors thrown either during server startup.
Also, I am aware of this SO thread (https://stackoverflow.com/questions/46159288/how-to-set-cache-control-private-with-applicationcontext-xml-in-spring-4-2-or-l ) where the accepted answer mentions there is no way to do this in the XML itself. I wanted to re-confirm if that is correct by trying to implement above solution but it is not working, but I don't see why.
答案1
得分: 1
按我所怀疑的,参数的传递方式存在问题。在 Spring 注入中,可变参数需要作为显式列表而不是参数的重载来传递(就像在 Java 中那样)。
因此,调用这种方法的正确方式是:
public void addCacheMapping(CacheControl cacheControl, String... paths)
在 Spring 的 applicationContext.xml
中如下所示:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref bean="webContentInterceptor"/>
</property>
<property name="targetMethod">
<value>addCacheMapping</value>
</property>
<property name="arguments">
<list>
<ref bean="myCacheControl" />
<list>
<value>/home</value>
<value>/dp/**</value>
<value>/**/b/*</value>
</list>
</list>
</property>
</bean>
正如你所见,我现在使用了 MethodInvokingFactoryBean
。不知何故,MethodInvokingBean
对我不起作用。
英文:
As I had suspected, there was an issue in the way the arguments were getting populated. The varargs in a spring injection need to be given as an explicit list instead of an overload of arguments (like it's done in Java).
So the correct way to invoke such a method -
public void addCacheMapping(CacheControl cacheControl, String... paths)
in spring applicationContext.xml is as follows -
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref bean="webContentInterceptor"/>
</property>
<property name="targetMethod">
<value>addCacheMapping</value>
</property>
<property name="arguments">
<list>
<ref bean="myCacheControl" />
<list>
<value>/home</value>
<value>/dp/**</value>
<value>/**/b/*</value>
</list>
</list>
</property>
</bean>
As you can see I have now used MethodInvokingFactoryBean
. Somehow MethodInvokingBean
did not work for me.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论