1、定义自定义视图:将其放入IoC容器中,
①getContentType():设置响应视图的类型
②render():处理最终的响应操作,InternalResourceView的这个方法也继承自它的父类AbstractView,只不过它的父类又声明了一个抽象方法renderMergedOutputModel(),并且在render()方法中调用了该方法,因此在实际运行中调用的实际是InternalResourceView中的renderMergedOutputModel()方法,在该方法中,进行了请求转发的操作。
package com.jd.view;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.View;
@Component
public class ToHello implements View {
@Override
public String getContentType() {
return "text/html";
}
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
PrintWriter out = response.getWriter();
out.print("Hello!");
out.flush();
out.close();
}
}
2、配置视图解析器,使用视图名字解析视图,如下所示:
order="0":通过下图我们可知,order值越大优先级越小,所以将order值设置为0,提升自定义视图的优先级。
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="0"></bean>
3、Controller定义Handler方法,该方法返回自定义视图的名字(默认情况下为首字母小写的类名),如下所示:
package com.jd.userinfo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserInfoController {
@RequestMapping("/userinfo/toView.do")
public String toView() {
return "toHello";//toHello是自定义视图类ToHello在IOC容器中默认的名字
}
}
演示:
过程如下:发送/userinfo/toView.do请求——>执行Handler方法,返回toView——>依据名字从Spring IoC容器获取ToHello对象——>执行ToHello对象render方法——>页面显示Hello!。
其详细过程是什么那?
通过debug模式运行:
我们知道发送一个请求必须由servelt调用service然后service再去doget或者dopost方法,对于DispatcherServlet会执行到doService()方法。
1、发送一个请求之后,会执行DispatcherServlet中的doService方法,
2、进而执行doService中的doDispath方法,
3、在doDispatch方法中,会执行下面代码,主要作用用于确定当前请求的handler处理器。
4、鼠标指向mappedHandler的时候,发现mappHandler是null,所以会再此确定当前请求的处理程序适配器。
此时handler是我们自定义的UserInfoController
5、接下来执行processDispatchResult方法,
6、进去processDispatchResult方法,第一个if此时exception是null,所以肯定会执行else,此时mv会被赋值,必定不为null,所以hi执行render方法,
7、进入render方法,此时引用的是我们自定义视图的对象,就是toHello。紧接着我们需要获取视图的名字,所以会调用resolveViewName方法,这个方法的名字也很好理解,就是引用视图名字。
8、进入resolveViewName方法,遍历此时的视图,自带的视图是InternalViewResolve和自定义视图ToHello,此时我们在appication配置中将其render设置为0,数值越小优先级越大,所以会优先使用我们自己的视图。
9、再次执行render方法,
10、此时toHello执行render方法,就会执行我们自定义的render方法中,进而返回Hello!在页面显示!