Resolución de vista SpringMVC
I. Descripción general de la vista de resolución SpringMVC
- Independientemente de si el controlador devuelve una cadena, ModelAndView, View se convertirá en un objeto ModelAndView, la vista se resuelve mediante el analizador de vistas y luego el salto de página.
Ver análisis de análisis de código fuente: dos interfaces importantes View y ViewResolver
- Ver vista:
- Ver el solucionador de vistas de ViewResolver:
En segundo lugar, la vista y el solucionador de vista
- Una vez que se ejecuta el método de procesamiento de solicitudes, finalmente se devuelve un objeto ModelAndView. Para aquellos métodos de procesamiento que devuelven String, View o ModeMap, Spring MVC también los ensamblará en un objeto ModelAndView internamente , que contiene el nombre lógico y la vista del objeto modelo
- Spring MVC usa ViewResolver para obtener el objeto de vista final (View). La vista final puede ser una JSP, o puede ser una vista de varias manifestaciones como Excel, JFreeChart, etc.
- Al procesador no le importa qué objeto de vista se usa para representar los datos del modelo al final, y el procesador se enfoca en el trabajo de producir datos del modelo, para realizar el desacoplamiento completo de MVC
2.1 Ver
-
La función de la vista es representar datos del modelo y presentar los datos en el modelo a los clientes de alguna forma.
-
Para lograr el desacoplamiento del modelo de vista y la tecnología de implementación específica, Spring define una interfaz de vista muy abstracta en el paquete org.springframework.web.servlet :
-
El solucionador de vistas crea una instancia del objeto de vista . Dado que las vistas no tienen estado , no tendrán problemas de seguridad de subprocesos
Clases de implementación de vistas de uso común:
2.2 Ver resolver
- SpringMVC proporciona diferentes estrategias para resolver el nombre lógico de la vista, el contexto Spring WEB se puede configurar con una o más políticas de resolución y especifica el orden entre ellas . Cada estrategia de mapeo corresponde a una clase de implementación de resolución de vista específica.
- La función del solucionador de vistas es relativamente simple: resuelve la vista lógica en un objeto de vista específico.
- Todos los resolutores de vistas deben implementar la interfaz ViewResolver:
Clases de implementación de resolución de vistas de uso común:
- Los programadores pueden elegir un resolutor de vista o mezclar varios resolutores de vista
- Cada resolución de vista implementa la interfaz Ordered y expone un atributo de orden. La prioridad del resolutor se puede especificar a través del atributo de orden . Cuanto menor sea el orden, mayor será la prioridad .
- SpringMVC analizará el nombre de la vista lógica de acuerdo con el orden de prioridad del solucionador de vista hasta que la resolución sea exitosa y se devuelva el objeto de vista; de lo contrario, se lanzará una ServletException
- InternalResourceViewResolver
- JSP es la tecnología de vista más común, puede usar InternalResourceViewResolve como un solucionador de vista:
- JSP es la tecnología de vista más común, puede usar InternalResourceViewResolve como un solucionador de vista:
Tres, JstlView (internacionalización)
-
Si se usa JSTL en el proyecto, SpringMVC convertirá automáticamente la vista de InternalResourceView a JstlView (depuración del punto de interrupción, agregue el paquete jar JSTL al proyecto y el analizador de vistas se modificará automáticamente a JstlView)
-
Si usa la etiqueta fmt de JSTL, debe configurar el archivo de recursos internacionalizado en el archivo de configuración SpringMVC
3.1 Proceso de uso de JstlView
-
Configure los archivos de configuración en dos idiomas: (convención de nomenclatura: base name_language code_country code.properties)
-
Agregue el paquete jar de la etiqueta jstl (depuración del punto de interrupción, el objeto View en este momento es JstlView)
-
Configurar archivos de recursos internacionalizados
<!--让SpringMVC管理国际化资源文件;配置一个资源文件管理器;id是必须叫messageSource --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <!-- basename指定基础名--> <property name="basename" value="i18n"></property> </bean>
-
Código del controlador
@Controller public class helloController { @RequestMapping("toLogin") public String login(){ System.out.println("login..."); return "login"; } }
-
La página de inicio de sesión (/WEB-INF/pages/login.jsp) usa la biblioteca de etiquetas fmt
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="toLogin"> <fmt:message key="username"/><input /><br/> <fmt:message key="password" /><input /><br/> <input type="submit" value="<fmt:message key='loginBtn' />" /> </form> </body> </html>
punto importante:
-
Debe pasar por el proceso de resolución de vista de SpringMVC . La gente creará un jstlView para ayudarlo a internacionalizarse rápidamente; no puede acceder directamente a la página de inicio de sesión y no puede acceder a ella a través del reenvío .
Analiza el código fuente:
3.2 El controlador de vista mapea la solicitud a una página
-
Si desea responder directamente a la página renderizada por SpringMVC , puede usar la etiqueta mvc: view-controller para lograr
<!-- 发送一个请求("toLoginPage");直接来到web-inf下的login页面;mvc名称空间下有一个请求映射标签 --> <!-- path="":指定哪个请求 view-name:指定映射给哪个视图 走了SpringMVC的整个流程,视图解析....不需要再写控制器方法 --> <mvc:view-controller path="/toLogin" view-name="login"/>
-
La configuración de <mvc: view-controller> provocará que otras rutas de solicitud fallen.
Solución: configure la etiqueta mvc: annotation-drive<!-- 开启mvc注解驱动模式;开启了mvc的开挂模式 --> <mvc:annotation-driven></mvc:annotation-driven>
Tres, reenviar y redirigir
- En circunstancias normales, el método del controlador devuelve un valor de tipo de cadena que se tratará como un nombre de vista lógica
- Si se devuelve con una cadena
forward:
oredirect:
prefijo, SpringMVC tendrán un tratamiento especial: reenviar: y redireccionar: como indicador, seguido de la cadena como URL para manejar - redirect: success.jsp: completará una redirección a success.jsp
- forward: success.jsp: completará una operación de reenvío a success.jsp
- el prefijo de reenvío especifica una operación de reenvío
/** * forward:/hello.jsp * forward:转发到一个页面 * /hello.jsp:转发到当前项目下的hello * * 注意:一定加/,如果不加/就是相对路径,容易出问题 */ @RequestMapping("/handle01") public String handle01(){ System.out.println("handle01"); return "forward:/hello.jsp"; }
- El prefijo de redireccionamiento especifica el redireccionamiento a la página.
/** * 重定向到hello.jsp页面 * 有前缀的转发和重定向操作,配置的视图解析器就不会进行拼串; * * 转发 forward:转发的路径 * 重定向 redirect:重定向的路径 * /hello.jsp:代表就是从当前项目下开始;SpringMVC会为路径自动的拼接上项目名 * * 原生的Servlet重定向/路径需要加上项目名才能成功 * response.sendRedirect("/hello.jsp") * @return */ @RequestMapping("handle03") public String handle03(){ System.out.println("handle03..."); return "redirect:/hello.jsp";//请求转发到hello.jsp页面 }
Cuatro, vista personalizada
-
Escriba un analizador de vista personalizado y vea la clase de implementación
Método de controlador:
/** * 自定义视图解析器和视图对象 */ @Controller public class MyViewResolverController { @RequestMapping("/handleplus") public String handleplus(Model model){ List<String> vname = new ArrayList<String>(); List<String> imgname = new ArrayList<String>(); vname.add("佟老师"); vname.add("康师傅"); imgname.add("萌萌"); model.addAttribute("video", vname); model.addAttribute("imgs", imgname); return "meinv:/login"; } }
Vista personalizada:
/** * 自定义视图 * @author ZB * */ public class MyView implements View { @Override public String getContentType() { // TODO Auto-generated method stub return "text/html"; } @Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { // TODO Auto-generated method stub System.out.println("进入到自定义视图中:"+model.get("viedo")); response.setContentType("text/html");//设置相应类型 response.getWriter().write("<h1>哈哈</h1>"); } }
Resolución de vista personalizada:
/** * 自定义视图解析器 * @author ZB * */ public class MyMeiNvViewResolver implements ViewResolver { @Override public View resolveViewName(String viewName, Locale locale) throws Exception { /** * 根据视图名返回视图对象 */ //处理以meinv为前缀的 if(viewName.startsWith("meinv:")){ return new MyView(); }else{ //如果不能处理返回null即可 return null; } } }
-
El solucionador de vistas debe colocarse en el contenedor ioc para que funcione y cree nuestro objeto de vista personalizado;
<bean class="com.zb.view.MyMeiNvViewResolver"> </bean>
Ingrese la URL / handleplus, informará 404: /05_SpringMVC_viewResolver/WEB-INF/pages/meinv:/login.jsp
Razón del análisis de depuración:
El solucionador de vistas InternalResourceViewResolver se encuentra antes que el solucionador de vistas personalizado para resolver: hacer que meinv: / login sea concatenado por InternalResourceViewResolver, y la ruta de la solicitud se escribe en WEB-INF / pages / meinv: /login.jsp, lo que da como resultado un 404
Solución: especifique la prioridad del solucionador de vistas
El solucionador de vistas personalizadas implementa la interfaz Ordered:
/**
* 自定义视图解析器
* @author ZB
*
*/
public class MyMeiNvViewResolver implements ViewResolver,Ordered {
private Integer order;
@Override
public View resolveViewName(String viewName, Locale locale)
throws Exception {
/**
* 根据视图名返回视图对象
*/
//处理以meinv为前缀的
if(viewName.startsWith("meinv:")){
return new MyView();
}else{
//如果不能处理返回null即可
return null;
}
}
@Override
public int getOrder() {
return order;
}
public void setOrder(Integer order){
this.order = order;
}
}
Especifique la prioridad en la configuración del resorte, cuanto menor sea el número, mayor será la prioridad
<bean class="com.zb.view.MyMeiNvViewResolver">
<!-- 自定义的视图解析器,value="1"数字越小优先级越高 -->
<property name="order" value="1"></property>
</bean>
En este punto: el solucionador de vistas personalizadas da prioridad para resolver: (obtenga la página de respuesta)