Spring:当url包含点和正确的扩展名时,无法解析带有名称的视图

时间:2017-08-08 02:32:59

标签: spring spring-mvc

这是我的控制器

@RequestMapping(value = "/download/{product}/{topic}/{key:.*}")
//@ResponseBody
public AjaxResult download(@PathVariable("product") String product, @PathVariable("topic") String topic,
    @PathVariable("key") String key, HttpServletRequest request, HttpServletResponse response) {

由于key路径变量可能包含点,因此使用正则表达式,类AjaxResult扩展LinkedHashMap并添加所有getter和setter,因此它可以返回json结果。视图解析器如下:

<bean
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="viewResolvers">
          <list>
            <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
        </list>      
    </property>
    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
        </list>
    </property>
</bean>

和转换器:

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="false">
        <bean id="fastJsonHttpMessageConverter"
            class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                    <value>text/plain;charset=UTF-8</value>
                    <value>application/json;charset=UTF-8</value>
                </list>
            </property>
            <property name="features">
                <array>
                    <!--<value>WriteMapNullValue</value> -->
                    <value>QuoteFieldNames</value>
                    <value>DisableCircularReferenceDetect</value>
                </array>
            </property>
        </bean>

        <bean id="stringHttpMessageConverter"
            class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8" index="0" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

并添加了<mvc:annotation-driven /> <mvc:default-servlet-handler />

问题是,当我访问:/download/product/topic/key.abc时,它可以正常工作,但是当访问:/download/product/topic/key.txt时,会发生错误:

javax.servlet.ServletException: Could not resolve view with name '/download/product/topic/key' in servlet with name ''
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1227)
    at org.springframework.test.web.servlet.TestDispatcherServlet.render(TestDispatcherServlet.java:105)

请注意两个网址之间的区别,当访问包含一个点和正确的文件扩展名的网址时,会发生错误。

您可能会看到我对控制器的注释@ResponseBody发表评论,如果添加@ResponseBody并访问网址/download/product/topic/key.txt,则会发生错误:

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:137)

有人可以帮忙吗?感谢。

更新

  1. 添加尾部斜杠,如Spring MVC @PathVariable getting truncated中所述,可以解决我的问题,即:
  2. @RequestMapping(value =&#34; / download / {product} / {topic} / {key:。*} /&#34;)

    以及使用/download/product/topic/key.txt/进行访问时,是否有任何其他解决方案无法更改@RequestMapping和网址中的值?

2 个答案:

答案 0 :(得分:0)

将以下内容添加到.xml  Spring配置的文件:

<context:annotation-config/> 
<mvc:annotation-driven />

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
  <list>
    <ref bean="jacksonMessageConverter"/>
  </list>
</property>
</bean>

您可以尝试将DispatcherServlet添加到web.xml文件中,您可以在下面找到代码:

 <servlet>
        <servlet-name>myServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:ApplicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>myServlet</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

答案 1 :(得分:0)

我解决了以下问题: 在我的spring servlet config xml中,有一个bean ContentNegotiatingViewResolver,所以我添加了一个bean ContentNegotiationManagerFactoryBean并将它的属性favorPathExtension设置为false,所以下面是我的配置文件:

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false"/>
    <property name="favorParameter" value="true"/>
</bean>
<bean
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">    
    <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
    <property name="viewResolvers">
          <list>
            <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
        </list>
    </property>
    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
        </list>
    </property>
</bean>

您在控制器中不需要@ResponseBody