配置多视图解析器(Thymeleaf和Json)



我正在尝试配置一个基于Spring的应用程序,我想配置两个视图解析器。从我的控制器,如果我只返回字符串名称,如"login",那么它应该由thyymeleaf解析器处理,而如果控制器的方法返回一个对象,那么应该使用适当的json视图。当我尝试按照下面的配置运行我的应用程序时,我得到以下错误

"无法解析名称为'login'的servlet视图。调度员"

请求你们看看下面的Java类。第一个是配置类,第二个是我试图使用的控制器。

package com.gojha.web;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.gojha.web")
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override 
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
        configurer.enable(); 
    }
    @Bean 
    public ViewResolver viewResolver(ContentNegotiationManager cnm) { 
        ContentNegotiatingViewResolver cnvr = new ContentNegotiatingViewResolver();
        cnvr.setContentNegotiationManager(cnm);
        return cnvr;
    }
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_JSON);
    }

    @Bean
    public TemplateResolver templateResolver() {
        TemplateResolver templateResolver = new ServletContextTemplateResolver();
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML5");
        return templateResolver;
    }
    @Bean
    public TemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        return templateEngine;
    }
    @Bean
    public ViewResolver viewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine((SpringTemplateEngine) templateEngine());
        return viewResolver;
    }
}
控制器

package com.gojha.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import static org.springframework.web.bind.annotation.RequestMethod.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
@RequestMapping("/")
public class LoginController {
    private RestTemplate restTemplate;
    private class Test {
        private String a;
        public Test() {
            super();
        }
        public Test(String a) {
            super();
            this.a = a;
        }
        public String getA() {
            return a;
        }
        public void setA(String a) {
            this.a = a;
        }
    }
    @Autowired
    public LoginController(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    @RequestMapping(method=GET)
    public String testing(){
        return "login";
    }
    @RequestMapping(method=GET, produces="application/json")
    public Test testing2(){
        return new Test("wow");
    }
}

我希望代码是自解释的

我通过更改配置文件和分配命令来查看解析器使其工作。从我的理解,它看起来像首先它试图解决视图使用ContentNegotiation,如果它失败了,回落到thymelef解析器。我将此标记为答案,如果有人有更好的方法,或建议的更正,请告诉我。

package com.gojha.web;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.gojha.web")
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_JSON);
    }
    @Bean
    public ViewResolver viewResolver() {
        TemplateResolver templateResolver = new ServletContextTemplateResolver();
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML5");
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine);
        viewResolver.setOrder(2);
        return viewResolver;
    }
    @Bean
    public ViewResolver cnViewResolver(ContentNegotiationManager cnm) {
        ContentNegotiatingViewResolver cnvr = new ContentNegotiatingViewResolver();
        cnvr.setContentNegotiationManager(cnm);
        cnvr.setOrder(1);
        List<View> views = new ArrayList<View>();
        views.add(jsonView());
        cnvr.setDefaultViews(views);
        return cnvr;
    }
    @Bean
    public View jsonView() {
        MappingJackson2JsonView view = new MappingJackson2JsonView();
        view.setPrettyPrint(true);
        return view;
    }
}

最新更新