bal*_*teo 96 spring spring-mvc circular-reference thymeleaf spring-mvc-test
我的一个控制器中有以下代码:
@Controller
@RequestMapping("/preference")
public class PreferenceController {
@RequestMapping(method = RequestMethod.GET, produces = "text/html")
public String preference() {
return "preference";
}
}
Run Code Online (Sandbox Code Playgroud)
我只是尝试使用Spring MVC测试来测试它,如下所示:
@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());
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下异常:
循环视图路径[preference]:将再次调度回当前处理程序URL [/ preference].检查您的ViewResolver设置!(提示:由于默认的视图名称生成,这可能是未指定视图的结果.)
我发现奇怪的是,当我加载包含模板和视图解析器的"完整"上下文配置时,它工作正常,如下所示:
<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>
Run Code Online (Sandbox Code Playgroud)
我很清楚,当应用程序使用此模板解析程序时,模板解析程序添加的前缀可确保没有"循环视图路径".
但那么我应该如何使用Spring MVC测试来测试我的应用程序?有人有任何线索吗?
小智 86
我使用@ResponseBody解决了这个问题,如下所示:
@RequestMapping(value = "/resturl", method = RequestMethod.GET, produces = {"application/json"})
@ResponseStatus(HttpStatus.OK)
@Transactional(value = "jpaTransactionManager")
public @ResponseBody List<DomainObject> findByResourceID(@PathParam("resourceID") String resourceID) {
Run Code Online (Sandbox Code Playgroud)
Sot*_*lis 59
这与Spring MVC测试无关.
当你没有声明a时ViewResolver,Spring会注册一个默认值InternalResourceViewResolver,它会创建JstlView用于渲染的实例View.
的JstlView类扩展InternalResourceView其是
适用于同一Web应用程序中的JSP或其他资源的包装器.将模型对象公开为请求属性,并使用javax.servlet.RequestDispatcher将请求转发到指定的资源URL.
此视图的URL应该指定Web应用程序中的资源,适用于RequestDispatcher的forward或include方法.
大胆是我的.换句话说,在渲染之前,视图将尝试获取RequestDispatcher到的视图forward().在此之前,它会检查以下内容
if (path.startsWith("/") ? uri.equals(path) : uri.equals(StringUtils.applyRelativePath(uri, path))) {
throw new ServletException("Circular view path [" + path + "]: would dispatch back " +
"to the current handler URL [" + uri + "] again. Check your ViewResolver setup! " +
"(Hint: This may be the result of an unspecified view, due to default view name generation.)");
}
Run Code Online (Sandbox Code Playgroud)
path视图名称在哪里,从中返回的是什么@Controller.在这个例子中,就是这样preference.该变量uri保存正在处理的请求的uri,即/context/preference.
上面的代码意识到,如果你要转发/context/preference,同一个servlet(因为处理前一个)将处理请求,你将进入无限循环.
在声明ThymeleafViewResolver和ServletContextTemplateResolver与特定的prefix和suffix,它构建的View方式不同,给它像一个路径
WEB-INF/web-templates/preference.html
Run Code Online (Sandbox Code Playgroud)
ThymeleafView实例ServletContext使用a 定位文件相对于路径
ServletContextResourceResolver
templateInputStream = resourceResolver.getResourceAsStream(templateProcessingParameters, resourceName);`
Run Code Online (Sandbox Code Playgroud)
最终
return servletContext.getResourceAsStream(resourceName);
Run Code Online (Sandbox Code Playgroud)
这将获得相对于ServletContext路径的资源.然后它可以使用它TemplateEngine来生成HTML.这里无法发生无限循环.
Bor*_*ris 48
@Controller → @RestController
我有同样的问题,我注意到我的控制器也注释了@Controller.更换它@RestController解决了这个问题.以下是Spring Web MVC的解释:
@RestController是一个组合注释,它本身用@Controller和@ResponseBody进行元注释,表示一个控制器,它的每个方法都继承了类型级@ResponseBody注释,因此直接写入响应体vs视图分辨率并使用HTML模板进行渲染.
Pio*_*ara 33
这就是我解决这个问题的方法:
@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();
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*wer 15
如果您实际上并不关心渲染视图,这是一个简单的修复.
创建InternalResourceViewResolver的子类,它不检查循环视图路径:
public class StandaloneMvcTestViewResolver extends InternalResourceViewResolver {
public StandaloneMvcTestViewResolver() {
super();
}
@Override
protected AbstractUrlBasedView buildView(final String viewName) throws Exception {
final InternalResourceView view = (InternalResourceView) super.buildView(viewName);
// prevent checking for circular view paths
view.setPreventDispatchLoop(false);
return view;
}
}
Run Code Online (Sandbox Code Playgroud)
然后用它设置你的测试:
MockMvc mockMvc;
@Before
public void setUp() {
final MyController controller = new MyController();
mockMvc =
MockMvcBuilders.standaloneSetup(controller)
.setViewResolvers(new StandaloneMvcTestViewResolver())
.build();
}
Run Code Online (Sandbox Code Playgroud)
Sar*_*oev 13
如果您使用的是Spring Boot,请将百万美元依赖项添加到您的pom.xml中:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
Old*_*led 12
我使用Spring Boot尝试加载网页,而不是测试,并遇到了这个问题.考虑到略有不同的情况,我的解决方案与上述方案略有不同.(虽然这些答案帮助我理解.)
我只需要在Maven中更改我的Spring Boot启动器依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
至:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
只是将'网络'改为'百里香',为我解决了问题.
Moz*_*ath 11
如果您还没有使用 a@RequestBody并且只使用@Controller,则解决此问题的最简单方法是使用@RestController而不是@Controller
小智 9
为我解决问题/后添加/preference:
@Test
public void circularViewPathIssue() throws Exception {
mockMvc.perform(get("/preference/"))
.andDo(print());
}
Run Code Online (Sandbox Code Playgroud)
小智 8
就我而言,我正在尝试 Kotlin + Spring boot,但遇到了 Circular View Path 问题。我在网上得到的所有建议都无济于事,直到我尝试了以下方法:
最初我使用注释我的控制器 @Controller
import org.springframework.stereotype.Controller
然后我替换@Controller为@RestController
import org.springframework.web.bind.annotation.RestController
它奏效了。
| 归档时间: |
|
| 查看次数: |
160890 次 |
| 最近记录: |