如何在Spring 5的Xml中配置WebContentInterceptor中的cacheControlMappings

huangapple go评论87阅读模式
英文:

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>

然后,我希望调用WebContentInterceptorpublic 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.

&lt;bean id=&quot;cacheControlFactory&quot; class=&quot;org.springframework.http.CacheControl&quot; factory-method=&quot;maxAge&quot;&gt;
	&lt;constructor-arg index=&quot;0&quot; value=&quot;3600&quot;/&gt;
	&lt;constructor-arg index=&quot;1&quot;&gt;
		&lt;value type=&quot;java.util.concurrent.TimeUnit&quot;&gt;SECONDS&lt;/value&gt;
	&lt;/constructor-arg&gt;
&lt;/bean&gt;

&lt;bean id=&quot;myCacheControl&quot; class=&quot;org.springframework.beans.factory.config.MethodInvokingFactoryBean&quot;&gt;
	&lt;property name=&quot;targetObject&quot;&gt;
		&lt;ref bean=&quot;cacheControlFactory&quot;/&gt;
	&lt;/property&gt;
	&lt;property name=&quot;targetMethod&quot;&gt;
		&lt;value&gt;cachePublic&lt;/value&gt;
	&lt;/property&gt;
&lt;/bean&gt;

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.

&lt;bean class=&quot;org.springframework.beans.factory.config.MethodInvokingBean&quot;&gt;
	&lt;property name=&quot;targetObject&quot;&gt;
		&lt;ref bean=&quot;webContentInterceptor&quot;/&gt;
	&lt;/property&gt;
	&lt;property name=&quot;targetMethod&quot;&gt;
		&lt;value&gt;addCacheMapping&lt;/value&gt;
	&lt;/property&gt;
	&lt;property name=&quot;arguments&quot;&gt;
		&lt;list&gt;
			&lt;ref bean=&quot;myCacheControl&quot; /&gt;
			&lt;value&gt;/home&lt;/value&gt;
			&lt;value&gt;/dp/**&lt;/value&gt;
			&lt;value&gt;/**/b/*&lt;/value&gt;
		&lt;/list&gt;
	&lt;/property&gt;
&lt;/bean&gt;

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 -

&lt;bean class=&quot;org.springframework.beans.factory.config.MethodInvokingFactoryBean&quot;&gt;
	&lt;property name=&quot;targetObject&quot;&gt;
		&lt;ref bean=&quot;webContentInterceptor&quot;/&gt;
	&lt;/property&gt;
	&lt;property name=&quot;targetMethod&quot;&gt;
		&lt;value&gt;addCacheMapping&lt;/value&gt;
	&lt;/property&gt;
	&lt;property name=&quot;arguments&quot;&gt;
		&lt;list&gt;
			&lt;ref bean=&quot;myCacheControl&quot; /&gt;
			&lt;list&gt;
				&lt;value&gt;/home&lt;/value&gt;
                &lt;value&gt;/dp/**&lt;/value&gt;
                &lt;value&gt;/**/b/*&lt;/value&gt;
			&lt;/list&gt;
		&lt;/list&gt;
	&lt;/property&gt;
&lt;/bean&gt;

As you can see I have now used MethodInvokingFactoryBean. Somehow MethodInvokingBean did not work for me.

huangapple
  • 本文由 发表于 2020年8月24日 19:14:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63559913.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定