Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which spring view resolver plays nice with angularjs?

I'm writing a webapp using angularjs and spring mvc as a REST service provider and as a partial view provider(I'm also using angular-ui-router so that I can have multiple nested partials). I currently don't have any use for template languages since I plan on doing everything in angular, however every single view resolver I've tried has some type of template language which clashes with angular and either crashes the application and/or fills my logs with errors.

First I tried using InternalResourceViewResolver but no luck as it seems that it only expects .jsp files and won't show anything else.

Then I tried using Thymeleaf. Thymeleaf follows the XML standard which forced me to rewrite most of my html to follow the xml requirements, and after I'd done that it died upon encountering a && inside an ng-show directive. So no luck with that either.

Then I tried Velocity. I've had most luck with velocity so far. It serves up html files nicely, doesn't stop upon encountering parse errors and allows me to serve up partial views the same way InternalResourceViewResolver does. However upon encountering angular variables prefixed by $ Velocity tries to parse them as VTL variables and fills my logs with messages like

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

Everything keeps working as it should but I'm not the one to just leave errors be, and I've found no way of disabling VTL.

That's my current experience with view resolvers.

I've also had an idea to treat .html files as static resources(which they kinda are before angular does it's magic) using mvc:resources but without any view resolver my application failed to start even if I set the main layout.html to be the welcome-file in web.xml

My question is. What should I use as a view resolver so that it plays nice with angularjs, and if I should even use view resolvers?

EDIT: I'm trying to use the ContentNegotiatingViewResolver and I get:

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 (contextconfig in 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";
    }
}
like image 506
MrPlow Avatar asked Jul 19 '14 08:07

MrPlow


People also ask

What is the default view resolver in Spring boot?

Thymeleaf view resolver works by surrounding the view name with a prefix and suffix. The default values of prefix and suffix are 'classpath:/templates/' and '. html', respectively. Spring Boot also provides an option to change the default value of prefix and suffix by setting spring.

Can we integrate Spring MVC with angular?

The architecture of a Spring MVC + Angular single page web app. The client is MVC-capable and contains all the presentation logic which is separated in a view layer, a controller layer, and a frontend services layer. After the initial application startup, only JSON data goes over the wire between client and server.

What is the default view resolver in Spring MVC?

2) The InternalResourceViewResolver is also the default view resolver of DispatcherServlet class, which acts as the front controller in the Spring MVC framework.


2 Answers

In order to use static resource(html,css,img,js) in spring, use a directory structure that looks like the following:

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"/>

Note you have to mention /static/img/image.jpg not just /image.jpg ..Same applies for css and js.

OR

You can also use content negotiating view resolver as shown below:

 <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 will use “ContentNegotiatingViewResolver” (order=1) to return a suitable view (based on file extension declared in “mediaTypes” property), if not match, then use “InternalResourceViewResolver” (order=2) to return a default JSP page.

<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>

Now from your jsp you can redirect to your static html page as well

   @Controller
    public class LayoutController {

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

    }

index.jsp

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

Now try to access your service through http://yourapp.com//index show the form action mentioned above.It will show the layout.html

click on a button or submit in jsp page to invoke the layout.html page

like image 131
Kuntal-G Avatar answered Nov 08 '22 23:11

Kuntal-G


I think ContentNegotiatingViewResolver is the best view resolver, because you will be able to integrate it with Jackson2 to response the data in JSON, XML or HTML text among others responses types that you need.

For example, look this approach.

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

like image 21
Dani Avatar answered Nov 08 '22 23:11

Dani