Tengo el siguiente código en uno de mis controladores:
@Controller
@RequestMapping("/preference")
public class PreferenceController {
@RequestMapping(method = RequestMethod.GET, produces = "text/html")
public String preference() {
return "preference";
}
}
Simplemente estoy tratando de probarlo usando la prueba Spring MVC de la siguiente manera:
@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());
}
}
Recibo la siguiente excepción:
Ruta de vista circular [preferencia]: se enviaría de nuevo a la URL del controlador actual [/ preferencia] nuevamente. ¡Compruebe la configuración de ViewResolver! (Sugerencia: esto puede ser el resultado de una vista no especificada, debido a la generación de nombre de vista predeterminada).
Lo que encuentro extraño es que funciona bien cuando cargo la configuración de contexto "completa" que incluye la plantilla y los resolutores de vista como se muestra a continuación:
<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>
Soy consciente de que el prefijo agregado por el solucionador de plantillas garantiza que no haya una "ruta de vista circular" cuando la aplicación utiliza este solucionador de plantillas.
Pero entonces, ¿cómo se supone que debo probar mi aplicación usando la prueba Spring MVC?

ViewResolverque usas cuando está fallando?@RestControllerlugar de@ControllerRespuestas:
Esto no tiene nada que ver con las pruebas Spring MVC.
Cuando no declara a
ViewResolver, Spring registra un valor predeterminadoInternalResourceViewResolverque crea instancias deJstlViewpara representar elView.La
JstlViewclase se extiendeInternalResourceViewque esAtrevido es mío. En otras palabras, la vista, antes de renderizar, intentará obtener un
RequestDispatcherdestinoforward(). Antes de hacer esto, verifica lo siguientedonde
pathestá el nombre de la vista, lo que devolvió del@Controller. En este ejemplo, eso espreference. La variableuricontiene el uri de la solicitud que se está manejando, que es/context/preference.El código anterior se da cuenta de que si tuviera que reenviar
/context/preference, el mismo servlet (ya que el mismo manejó el anterior) manejaría la solicitud y entraría en un bucle sin fin.Cuando declaras a
ThymeleafViewResolvery aServletContextTemplateResolvercon unprefixy específicosuffix, se construye de maneraViewdiferente, dándole una ruta comoThymeleafViewinstancias localizan el archivo en relación con laServletContextruta mediante unServletContextResourceResolverque eventualmente
Esto obtiene un recurso que es relativo a la
ServletContextruta. Luego puede usar elTemplateEnginepara generar el HTML. No hay forma de que ocurra un ciclo sin fin aquí.fuente
ThymleafViewResolverelViewse resuelve como un archivo relativo alprefixysuffixusted proporciona. Cuando no usa esa resolución, Spring usa un valor predeterminadoInternalResourceViewResolverque busca recursos con una extensiónRequestDispatcher. Este recurso puede ser unServlet. En este caso es porque la ruta se/preferenceasigna a suDispatcherServlet.ViewResolver. Ya seaThymeleafViewResolvercomo en su pregunta, la suya propia configuradaInternalResourceViewResolvero cambie el nombre de la vista que está devolviendo en su controlador.@RequestMappingmétodo de controlador anotado con unStringtipo de retorno (y no@ResponseBody) tiene su valor de retorno manejado por unViewNameMethodReturnValueHandlerque interpreta la Cadena como un nombre de vista y lo usa para pasar por el proceso que explico en mi respuesta. Con@ResponseBody, Spring MVC usará en su lugar,RequestResponseBodyMethodProcessorque en su lugar escribe la cadena directamente en la respuesta HTTP, es decir. sin resolución de vista.Resolví este problema usando @ResponseBody como se muestra a continuación:
fuente
List<DomainObject>.@Controller→@RestControllerTuve el mismo problema y noté que mi controlador también estaba anotado con
@Controller. Reemplazarlo con@RestControllerresolvió el problema. Aquí está la explicación de Spring Web MVC :fuente
@ControllerAdvicecon unhandleXyException, que devolvía mi propio objeto en lugar de un ResponseEntity. Agregar@RestControllerencima de la@ControllerAdviceanotación funcionó y el problema desapareció.Así es como resolví este problema:
fuente
Estoy usando Spring Boot para intentar cargar una página web, no para probar, y tuve este problema. Mi solución fue un poco diferente a las anteriores considerando las circunstancias ligeramente diferentes. (aunque esas respuestas me ayudaron a entender).
Simplemente tuve que cambiar mi dependencia de arranque Spring Boot en Maven de:
a:
Simplemente cambiando la 'web' a 'thymeleaf' solucionó el problema.
fuente
Aquí hay una solución fácil si realmente no le importa renderizar la vista.
Cree una subclase de InternalResourceViewResolver que no compruebe las rutas de vista circular:
Luego configure su prueba con él:
fuente
Si está utilizando Spring Boot, agregue la dependencia de thymeleaf en su pom.xml:
fuente
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>Agregar
/después de/preferenceresolver el problema para mí:fuente
En mi caso, estaba probando Kotlin + Spring boot y me metí en el problema de Circular View Path. Todas las sugerencias que recibí en línea no pudieron ayudar, hasta que intenté lo siguiente:
Originalmente había anotado mi controlador usando
@Controllerimport org.springframework.stereotype.ControllerLuego reemplacé
@Controllercon@RestControllerimport org.springframework.web.bind.annotation.RestControllerY funcionó.
fuente
si no ha usado un @RequestBody y lo está usando solo
@Controller, la forma más sencilla de solucionar esto es usar en@RestControllerlugar de@Controllerfuente
Agregue la anotación
@ResponseBodya su método return.fuente
Estoy usando Spring Boot con Thymeleaf. Esto es lo que funcionó para mí. Hay respuestas similares con JSP, pero tenga en cuenta que estoy usando HTML, no JSP, y están en la carpeta
src/main/resources/templatescomo en un proyecto Spring Boot estándar como se explica aquí . Este también podría ser tu caso.Espero que esto ayude.
fuente
Al ejecutar Spring Boot + Freemarker si aparece la página:
Página de error de etiqueta blanca Esta aplicación no tiene un mapeo explícito para / error, por lo que está viendo esto como una alternativa.
En spring-boot-starter-parent 2.2.1.RELEASE versión freemarker no funciona:
spring.freemarker.suffix = .ftl
fuente
Para Thymeleaf:
Acabo de comenzar a usar Spring 4 y Thymeleaf, cuando encontré este error, se resolvió agregando:
fuente
Al usar la
@Controlleranotación, necesita@RequestMappingy@ResponseBodyanotaciones. Vuelva a intentarlo después de agregar una anotación@ResponseBodyfuente
Utilizo la anotación para configurar la aplicación web Spring, el problema se resuelve agregando un
InternalResourceViewResolverbean a la configuración. Espero que sea de ayuda.fuente
Esto sucede porque Spring está eliminando la "preferencia" y agregando la "preferencia" nuevamente haciendo la misma ruta que la solicitud Uri.
Sucediendo así: solicitud Uri: "/ preferencia"
eliminar "preferencia": "/"
añadir ruta: "/" + "preferencia"
cadena final: "/ preferencia"
Esto se está metiendo en un bucle que Spring le notifica lanzando una excepción.
Es mejor para su interés dar un nombre de vista diferente, como "ver preferencia" o cualquier cosa que desee.
fuente
intente agregar la dependencia compile ("org.springframework.boot: spring-boot-starter-thymeleaf") a su archivo gradle. Thhymeleaf ayuda a mapear vistas.
fuente
En mi caso, tuve este problema al intentar servir páginas JSP usando la aplicación Spring Boot.
Esto es lo que funcionó para mí:
application.properties
pom.xml
Para habilitar el soporte para JSP, necesitaríamos agregar una dependencia en tomcat-embed-jasper.
fuente
Otro enfoque simple:
fuente