【问题标题】:Which spring view resolver plays nice with angularjs?哪个弹簧视图解析器与 angularjs 配合得很好?
【发布时间】:2014-09-10 08:50:49
【问题描述】:

我正在编写一个使用 angularjs 和 spring mvc 作为 REST 服务提供者和部分视图提供者的 web 应用程序(我也在使用 angular-ui-router 以便我可以有多个嵌套的部分)。我目前对模板语言没有任何用处,因为我打算用 Angular 做所有事情,但是我尝试过的每一个视图解析器都有某种类型的模板语言,它与 Angular 冲突,或者导致应用程序崩溃和/或填充我的日志有错误。

首先我尝试使用 InternalResourceViewResolver 但没有运气,因为它似乎只需要 .jsp 文件并且不会显示其他任何内容。

然后我尝试使用 Thymeleaf。 Thymeleaf 遵循 XML 标准,这迫使我重写我的大部分 html 以遵循 xml 要求,并且在我完成之后,它在 ng-show 指令中遇到 && 时死亡。所以也没有运气。

然后我尝试了 Velocity。到目前为止,我在速度方面最幸运。它很好地提供了 html 文件,在遇到解析错误时不会停止,并允许我以与 InternalResourceViewResolver 相同的方式提供部分视图。然而,在遇到以$为前缀的角度变量时,Velocity 会尝试将它们解析为 VTL 变量,并在我的日志中填充类似

的消息

velocity - Null reference [template 'clients/createOrEdit.html', line 1, column 65] : $invalid cannot be resolved.

一切都按应有的方式正常运行,但我不是那种只会留下错误的人,而且我找不到禁用 VTL 的方法。

这是我目前使用视图解析器的经验。

我也有一个想法,使用mvc:resources 将 .html 文件视为静态资源(它们有点在 Angular 之前是魔法),但没有任何视图解析器,即使我设置了主布局,我的应用程序也无法启动.html 成为 web.xml 中的欢迎文件

我的问题是。我应该使用什么作为视图解析器,以便它与 angularjs 配合得很好,如果我什至应该使用视图解析器?

编辑:我正在尝试使用ContentNegotiatingViewResolver,我得到:

DEBUG ContentNegotiatingViewResolver - Requested media types are [text/html] based on Accept header types and producible media types [*/*])
DEBUG ContentNegotiatingViewResolver - No acceptable view found; returning null
DEBUG DispatcherServlet - Could not complete request
javax.servlet.ServletException: Could not resolve view with name 'layout.html' in servlet with name 'springDispatcherServlet'

webapp-config.xml(dispatcher servlet 中的上下文配置)

    <mvc:annotation-driven />

    <!-- Resources -->
    <mvc:resources location="/libs/" mapping="/libs/**" />
    <mvc:resources location="/css/" mapping="/css/**" />
    <mvc:resources location="/js/" mapping="/js/**" />
    <!-- Angular application data -->
    <mvc:resources location="/WEB-INF/appjs/" mapping="/appjs/**" />
    <!-- View locations -->
    <mvc:resources location="/WEB-INF/html/" mapping="/**"/>

    <!-- Controllers -->
    <context:component-scan base-package="com.mrplow.controller" />

    <!-- Views -->
    <util:map id="contentMediaTypes">
        <entry key="json" value="application/json" />
        <entry key="html" value="text/html" />
    </util:map>

<!--    <util:list id="defaultViews"> -->
<!--        <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />       -->
<!--    </util:list> -->

    <bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"
    p:order="1"
    p:ignoreAcceptHeader="false"
    p:defaultContentType="text/html"
    p:mediaTypes-ref="contentMediaTypes" /> 

LayoutController.java

@Controller
@RequestMapping("/")
public class LayoutController {

    @RequestMapping
    public String getIndexPage() {
        return "layout";
    }
}

【问题讨论】:

    标签: spring angularjs spring-mvc


    【解决方案1】:

    为了在spring中使用静态资源(html,css,img,js),使用如下目录结构:

    src/
       package/
       LayoutController.java
    WebContent/
       WEB-INF/
        static/
          html/
           layout.html
          images/
           image.jpg
          css/
           test.css
          js/
           main.js
         web.xml
        springmvc-servlet.xml
    
    
    
    @Controller 
    public class LayoutController {
    
     @RequestMapping("/staticPage") 
    public String getIndexPage() { 
    return "layout.htm"; 
    
    } }
    
    
    
      <!-- in spring config file -->
     <mvc:resources mapping="/static/**" location="/WEB-INF/static/" />
    

    layout.html

    <h1>Page with image</h1>
    <img src="/static/img/image.jpg"/>
    

    请注意,您必须提及 /static/img/image.jpg 而不仅仅是 /image.jpg ..同样适用于 css 和 js。

    您也可以使用内容协商视图解析器,如下所示:

     <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
              <property name="order" value="1" />
              <property name="mediaTypes">
                <map>
                   <entry key="json" value="application/json" />
                   <entry key="xml" value="application/xml" />
                   <entry key="rss" value="application/rss+xml" />
                    <entry key="html" value="text/html"/>
                </map>
              </property>
    
              <property name="defaultViews">
                <list>
                  <!-- JSON View -->
                  <bean
                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                  </bean>
    

    Spring MVC 将使用“ContentNegotiatingViewResolver”(order=1)返回一个合适的视图(基于“mediaTypes”属性中声明的文件扩展名),如果不匹配,则使用“InternalResourceViewResolver”( order=2) 返回一个默认的 JSP 页面。

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

    现在,您也可以从您的 jsp 重定向到您的静态 html 页面

       @Controller
        public class LayoutController {
    
            @RequestMapping("/index")
            public String getIndexPage() {
                return "index";
            }
    
        }
    

    index.jsp

    <form:form method="GET" action="/static/html/layout.html">
    

    现在尝试通过http://yourapp.com//index 访问您的服务显示上述表单操作。它将显示layout.html

    点击按钮或在jsp页面中提交调用layout.html页面

    【讨论】:

    • 谢谢。一个问题。媒体类型提到 xml - application/xml 。这也算 html 文件?
    • 是的,您可以将它用于 html 。我已经更新了我的答案。请检查
    • 我明白了。还有一个问题。它在哪里查找文件?它似乎无法找到我的观点。我将使用当前配置更新 OP
    • 我已经更新了我的答案。请更新您的配置。希望它能解决您的问题!
    • 我已经按照你说的做了,但我仍然遇到同样的错误。我也尝试将return "layout.html;" 更改为return "html/layout.html;" 但没有区别
    【解决方案2】:

    我认为 ContentNegotiatingViewResolver 是最好的视图解析器,因为您将能够将它与 Jackson2 集成以响应 JSON、XML 或 HTML 文本中的数据以及您需要的其他响应类型。

    例如,看看这个方法。

    http://hillert.blogspot.com.es/2011/01/rest-with-spring-contentnegotiatingview.html

    【讨论】:

    • 谢谢。一个问题。媒体类型提到 xml - application/xml 。这也算 html 文件?
    • 我不知道我是否理解你的问题。但是 HTML 文件的内容类型是“text/html”而不是“application/xml”。在 google 中搜索,您可以找到所有资源的不同内容类型。另一方面,了解@RequestMapping 和消费/生产属性,用于在方法级别指定所有问题。
    【解决方案3】:

    对于寻找如何使用 ContentNegotiatingViewResolver 制作解决方案以在新版本的 Spring 中工作的人:

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
        <property name="defaultViews">
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
        </property>
    </bean>
    

    然后在 ContentNegotiationManagerFactoryBean 中配置您需要的扩展:

    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="mediaTypes">
            <props>
                <prop key="json">application/json</prop>
                <prop key="html">text/html</prop>
                <prop key="xml">application/xml</prop>
                // and so on
            </props>
        </property>
    
        <property name="ignoreAcceptHeader" value="true"/>
    </bean>
    

    【讨论】:

      猜你喜欢
      • 2014-04-07
      • 2016-02-10
      • 2010-11-14
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 2011-11-27
      • 1970-01-01
      相关资源
      最近更新 更多