java - Spring不解析具有相同URL前缀的JSP和JSON

标签 java jsp rest spring-mvc

我的目标:

  1. http://host:port/myApp/about返回一个名为 about.jsp 的 jsp 页面
  2. http://host:port/myApp/about/log是返回 JSON 的服务调用

我的 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" ...>
<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:log4j.xml</param-value>
</context-param>
<context-param>
    <param-name>log4jExposeWebAppRoot</param-name>
    <param-value>false</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<servlet>
    <servlet-name>myApp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            ...
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>myApp</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

我的servlet.xml(使用Spring 3.0.3.RELEASE):

<beans ...>

<mvc:annotation-driven />
<context:component-scan ... />

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="15728640" /> <!-- 15 MB -->
    <property name="MaxInMemorySize" value="15728640" /> <!-- 15 MB -->
</bean>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="order" value="1" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="2" />
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
        </map>
    </property>
    <property name="defaultContentType" value="application/json" />
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <constructor-arg>
                    <bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
                </constructor-arg>
            </bean>
        </list>
    </property>
    <property name="ignoreAcceptHeader" value="true" />
</bean>
</beans>

我的 Controller :

@Controller
@RequestMapping("about")
public class AboutController {

    @RequestMapping(method=GET)
    public String getStats() {
        return "about";
    }

    @RequestMapping(value="log", method=GET)
    public @ResponseBody List<String> getLog() {
        ...
    }
}

在服务器(jetty 6,servlet-api 2.5)启动时我看到:

INFO org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/about/log] onto handler [AboutController@63843ca4]
INFO org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/about/log.*] onto handler [AboutController@63843ca4]
INFO org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/about/log/] onto handler [AboutController@63843ca4]
INFO org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/about] onto handler [AboutController@63843ca4]
INFO org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/about.*] onto handler [AboutController@63843ca4]
INFO org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/about/] onto handler [AboutController@63843ca4]

上述目标设置的结果:

  1. 产生错误:

    WARN org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/myApp/WEB-INF/views/about.jsp] in DispatcherServlet with name 'myApp'  
    
  2. 按预期工作

我检查/尝试过的事情:

  • WEB-INF/views/about.jsp确实存在
  • 我已在 Controller 中为这两种方法设置了断点,并且它们都被正确调用;退出 Controller 类后的某个时间发生故障
  • 顺序为InternalResourceViewResolver故意设置为第一。我知道the Spring docs建议不要这样做,但是当我尝试把它放在最后时,我得到一个空的 { }返回,我认为是因为 ContentNegotiatingViewResolver选取“about”字符串并以某种方式解释它。我对顺序没有要求,但是ContentNegotiatingViewResolver中的设置需要保持现状(除非绝对有必要改变)。
  • 将 web.xml 中的 url-pattern 设置为 <url-pattern>/</url-pattern> ,但这会破坏对静态资源的引用(这不是一个选项,因为这些资源当前被许多第三方在生产中使用)
  • 将 web.xml 中的 url-pattern 设置为 <url-pattern>/about/*</url-pattern> ,但随后我得到了与上面列出的相反的结果:

    1. 按预期工作
    2. 产生错误:

      WARN org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/myApp/about/log.json] in DispatcherServlet with name 'myApp'
      

    有趣的是,网址 http://host:port/myApp/about/about/log 确实适用于此网址模式

所以,我有点困惑要解决什么问题才能实现既定目标。

最佳答案

使用InternalResourceViewResolver有什么具体需要吗?

要配置jackson插件,我们只需要

 <mvc:annotation-driven />

尝试使用此 XML

<beans ...>
 <context:annotation-config />
<mvc:annotation-driven />
<context:component-scan ... />

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="15728640" /> <!-- 15 MB -->
    <property name="MaxInMemorySize" value="15728640" /> <!-- 15 MB -->
</bean>


<bean id="viewResolver"
      class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>
</beans>

关于java - Spring不解析具有相同URL前缀的JSP和JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10955866/

相关文章:

java - 通过 id 查找父 View

jsp - 在jsp中显示\u0096

php - Google Api for PHP(Drive API)导出为 .pdf 上传的 .docx 文件

java - 操作从 postForObject 返回的 JSON

rest - 404 状态代码是否适用于插入时不存在的实体?

java - 工具提示不换行/忽略最大宽度

java - 如何控制 ApplicationListener bean 的调用顺序?

jsp - 升级正在运行的 Tomcat servlet

java - JSP/Servlet Web 应用程序中的 XSS 预防

java - com.google.firebase.database.DatabaseException : Expected a List while deserializing, 但得到了一个类 java.util.HashMap