How to avoid the “Circular view path” exception wi

2019-01-03 13:57发布

I have the following code in one of my controllers:

@Controller
@RequestMapping("/preference")
public class PreferenceController {

    @RequestMapping(method = RequestMethod.GET, produces = "text/html")
    public String preference() {
        return "preference";
    }
}

I am simply trying to test it using Spring MVC test as follows:

@ContextConfiguration
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class PreferenceControllerTest {

    @Autowired
    private WebApplicationContext ctx;

    private MockMvc mockMvc;
    @Before
    public void setup() {
        mockMvc = webAppContextSetup(ctx).build();
    }

    @Test
    public void circularViewPathIssue() throws Exception {
        mockMvc.perform(get("/preference"))
               .andDo(print());
    }
}

I am getting the following exception:

Circular view path [preference]: would dispatch back to the current handler URL [/preference] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)

What I find strange is that it works fine when I load the "full" context configuration that includes the template and view resolvers as shown below:

<bean class="org.thymeleaf.templateresolver.ServletContextTemplateResolver" id="webTemplateResolver">
    <property name="prefix" value="WEB-INF/web-templates/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
    <property name="characterEncoding" value="UTF-8" />
    <property name="order" value="2" />
    <property name="cacheable" value="false" />
</bean>

I am well aware that the prefix added by the template resolver ensures that there are not "circular view path" when the app uses this template resolver.

But then how I am supposed to test my app using Spring MVC test? Has anyone got any clue?

14条回答
可以哭但决不认输i
2楼-- · 2019-01-03 14:17

For Thymeleaf:

I just began using spring 4 and thymeleaf, when I encountered this error it was resolved by adding:

<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
  <property name="templateEngine" ref="templateEngine" />
  <property name="order" value="0" />
</bean> 
查看更多
男人必须洒脱
3楼-- · 2019-01-03 14:17

This is happening because Spring is removing "preference" and appending the "preference" again making the same path as the request Uri.

Happening like this : request Uri: "/preference"

remove "preference": "/"

append path: "/"+"preference"

end string: "/preference"

This is getting into a loop which the Spring notifies you by throwing exception.

Its best in your interest to give a different view name like "preferenceView" or anything you like.

查看更多
姐就是有狂的资本
4楼-- · 2019-01-03 14:18

@Controller@RestController

I had the same issue and I noticed that my controller was also annotated with @Controller. Replacing it with @RestController solved the issue. Here is the explanation from Spring Web MVC:

@RestController is a composed annotation that is itself meta-annotated with @Controller and @ResponseBody indicating a controller whose every method inherits the type-level @ResponseBody annotation and therefore writes directly to the response body vs view resolution and rendering with an HTML template.

查看更多
Bombasti
5楼-- · 2019-01-03 14:20

try adding compile("org.springframework.boot:spring-boot-starter-thymeleaf") dependency to your gradle file.Thymeleaf helps mapping views.

查看更多
Fickle 薄情
6楼-- · 2019-01-03 14:24

This is how I solved this problem:

@Before
    public void setup() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/view/");
        viewResolver.setSuffix(".jsp");

        mockMvc = MockMvcBuilders.standaloneSetup(new HelpController())
                                 .setViewResolvers(viewResolver)
                                 .build();
    }
查看更多
forever°为你锁心
7楼-- · 2019-01-03 14:24

I use the annotation to configure spring web app, the problem solved by adding a InternalResourceViewResolver bean to the configuration. Hope it would be helpful.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.example.springmvc" })
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public InternalResourceViewResolver internalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/jsp/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}
查看更多
登录 后发表回答