SpringMVC 的 Controller 返回各种视图的处理方式
SpringMVC 的 Controller 可以返回各种各样的视图。比如 JSP, JSON, Velocity, FreeMarker, XML, PDF, Excel, 还有Html字符流 等等。那它们该如何的进行处理的呢?这里就涉及到 各种视图(View)对应的各种视图解析器(ViewResolver). 基本上上面说的每一种视图就对应用一种视图解析器来处理。基本上各种视图解析器大致上可以分为两类:一是基于URL的视图解析器;一种是其它解析器;所谓的UrlBasedViewResolver,就是将返回值作为最终视图的url的一部分,然后和相关配置组合起来,就是最终的视图地址url. 我们看下UrlBasedViewResolver的解析器有哪些:
1. 返回JSP
返回JSP是最简单的,JSP视图的视图解析器为 InternalResourceViewResolver,也是一个UrlBasedViewResolver解析器。其对应的解析器的配置一般如下:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
使用该例子,我们好好理解下什么是 “基于URL” 的视图解析器,比如我们的 Controller 中最后的返回的处理代码为: return "index"; 那么“基于URL” 的视图解析器就会将返回值 “index” 作为最后视图的URL的一部分,然后结合上面的配置 <property name="prefix" value="/WEB-INF/jsp/"/> 和 <property name="suffix" value=".jsp"/>,最后得到最终的URL: "/WEB-INF/jsp/" + "index" + ".jsp" == "/WEB-INF/jsp/index.jsp"
这就是所谓的 “基于URL” 的视图解析器的工作方式。
2. 返回 HTML 页面
我们知道在Servlet中,我们是可以直接在其中打印输出HTML字符流到最终页面,比如下面的代码来自阿里巴巴的支付宝的接入示例中的代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
// ... ...
//建立请求
String sHtmlText = AlipaySubmit.buildRequest(sParaTemp,"get","确认");
response.getWriter().println(sHtmlText);
}
/**
* 建立请求,以表单HTML形式构造(默认)
* @param sParaTemp 请求参数数组
* @param strMethod 提交方式。两个值可选:post、get
* @param strButtonName 确认按钮显示文字
* @return 提交表单HTML文本
*/
public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName) {
//待请求参数数组
Map<String, String> sPara = buildRequestPara(sParaTemp);
List<String> keys = new ArrayList<String>(sPara.keySet()); StringBuffer sbHtml = new StringBuffer();
sbHtml.append("<!doctype html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
sbHtml.append("<title>支付宝即时到账交易接口</title></head><body>");
sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\" action=\"" + ALIPAY_GATEWAY_NEW
+ "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod
+ "\">"); for (int i = 0; i < keys.size(); i++) {
String name = (String) keys.get(i);
String value = (String) sPara.get(name); sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
} //submit按钮控件请不要含有name属性
sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");
sbHtml.append("<script>document.forms['alipaysubmit'].submit();</script>");
sbHtml.append("</body></html>");
return sbHtml.toString();
}
很显然,Servlet直接将HTML的字符流输出到了浏览器端,那么在SpringMVC中该如何做呢?其实在SpringMVC中我们也是可以如下实现的:
@RequestMapping(value="/getPage")
public void writeSubmitHtml(Reader reader, Writer writer, HttpSession session) throws IOException {
User user = (User) session.getAttribute(ConstantConfig.LONGIN_USER);
StringBuffer sbHtml = new StringBuffer();
sbHtml.append("<!doctype html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
sbHtml.append("<title>支付宝即时到账交易接口</title></head><body>"+ user.getNo() +"</body></html>");
writer.write(sbHtml.toString());
}
我们看到我们直接使用了参数 Writer writer,返回值为 void, 其实参数 Writer writer 也可以换成 PrintWriter writer; 直接写出HTML的字符流。
我们也知道在Servlet中,我们是可以直接forward或者redirecit到html页面,所以我们也可以如下在springmvc中返回到html页面:
@RequestMapping(value="/htmlView")
public void htmlView(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
// ...
request.getRequestDispatcher("index.html").forward(request, response);
//response.sendRedirect("http://www.baidu.com");
}
这里,我们体会到了:springmvc他是建立在servlet之上的,所以在servlet中能够做到的,同样在springmvc一样有效。
3. 返回JSON格式
返回JSON格式在SpringMVC中有多种处理方式,一种是使用SpirngMVC自带的 MappingJackson2JsonView 来处理,一种是自己写代码将返回值JSON格式化,然后直接用PrintWrite类型的对象写出就行了。
1)直接用PrintWrite类型的对象写出JSON格式
@RequiresRoles(value={"student"})
@RequestMapping(value="/queryScoreForStudent")
public void queryScoreForStudent(ScoreQueryParam param, HttpSession sesion, PrintWriter printWriter){
Student student = (Student)sesion.getAttribute(ConstantConfig.LONGIN_STUDENT);
param.setStudentId(student.getId());
PageBean<StudentScore> scoreList = this.studentCourseService.queryScoreForStudent(param);
if(scoreList != null && scoreList.getSize() > 0){
Map<String, Object> map = new HashMap<>();
map.put("result", "ok");
map.put("data", scoreList);
printWriter.write(JSON.toJSONString(map));
}
}
如上代码所示,我们在方法中加入了 PrintWriter printWriter 参数,最后的返回结果使用了fastjson库来格式化最后的返回的对象map. 然后使用printWriter写出,就行了。我们看到方法上的注解并没有使用 @ResponseBody. 当然最好这里是在方法上加上 @ResponseBody,但是因为返回的map已经是JSON格式的,所以并不需要配置 MappingJackson2JsonView !
2)使用MappingJackson2JsonView 配合@ResponseBody来返回JSON格式
首先需要进行相关的视图解析器的配置:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="atom" value="application/atom+xml"/>
<entry key="html" value="text/html"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="viewResolvers">
<list>
<!-- <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/> -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</list>
</property>
</bean>
这里用到了 ContentNegotiatingViewResolver ,“内容协商视图解析器”,其实就是根据返回什么类型的视图,就协商使用哪种视图解析器。如果返回jsp就使用InternalResourceViewResolver视图解析器,如果返回JSON格式就使用MappingJackson2JsonView来处理。如此而已。在 <property name="viewResolvers"> 下的<list> 标签下,还可以加入其他的各种视图解析器的配置。
配置了 MappingJackson2JsonView 之后,就没有必要在自己手动 JSON格式化了,上面的例子,可以改成:
@RequiresRoles(value={"student"})
@RequestMapping(value="/queryScoreForStudent")
@ResponseBody
public Map<String, Object> queryScoreForStudent(ScoreQueryParam param, HttpSession sesion){
Student student = (Student)sesion.getAttribute(ConstantConfig.LONGIN_STUDENT);
param.setStudentId(student.getId());
PageBean<StudentScore> scoreList = this.studentCourseService.queryScoreForStudent(param);
System.out.println(JSON.toJSONString(scoreList));
if(scoreList != null && scoreList.getSize() > 0){
Map<String, Object> map = new HashMap<>();
map.put("result", "ok");
map.put("data", scoreList);
return map;
}
}
其他格式Velocity, FreeMarker, XML, PDF, Excel等视图的处理,后面有时间在补上。
SpringMVC 的 Controller 返回各种视图的处理方式的更多相关文章
- SpringMVC中controller返回图片(转)
本文转自:http://blog.csdn.net/u011637069/article/details/51112187 SpringMVC中controller通过返回ModelAndView然后 ...
- springMVC对于Controller返回值的可选类型
2018-01-11 对于springMVC处理方法支持支持一系列的返回方式: (1)ModelAndView (2)Model (3)ModelMap (4)Map (5)View (6)Stri ...
- springMVC的controller返回值
1.可以返回ModelAndView 2.可以返回一个String字符串:即一个jsp页面的逻辑视图名,这个在springMVC.xml中可以配置此页面逻辑视图的前缀和后缀 3.可以返回void类型: ...
- SpringMVC总结三:请求Controller返回视图类型以及请求方式、参数介绍
视图解析,请求Controller返回的视图类型: @Controller @RequestMapping("/test") public class TestController ...
- 关于在@Controller所返回的视图的css,js文件404问题
本人在使用layui打开一个请求后台的页面时,页面成功由controller重定向到了正确的位置,然而几乎所有的js文件和css文件都报404,并且确定这些css文件还有js文件的引入的路径都是正确的 ...
- SpringMVC 返回 html 视图页面,SpringMVC与Servlet,Servlet重定向与转发
1. SpringMVC与Servlet的关系 SpringMVC框架是建立在Servlet之上的,提供各种功能,各种封装,各种方便的同时,它一点儿也没有限制Servlet,我们完全可以在Spring ...
- springMVC中controller的几种返回类型
==网文1,还不错,感觉比较老旧springMVC中controller的几种返回类型 - CSDN博客http://blog.csdn.net/qq_16071145/article/details ...
- SpringMVC Controller 返回值几种类型
SpringMVC Controller 返回值几种类型 2016年06月21日 19:31:14 为who而生 阅读数:4189 标签: Controller 返回值类型spring mvc 更多 ...
- SpringMVC——-Controller返回格式化数据如JSON、XML的配置方式和机制
1.本文内容 我们在Web项目开发过程中,一般来说访问一个处理器,然后会返回一个视图,或者跳转到另外的处理器.但是随着项目越来越复杂,需求越来越复杂,对于处理器返回数据的类型要求也越来越多.比如要求能 ...
随机推荐
- sqlserver锁表、解锁、查看锁表
sqlserver锁表.解锁.查看锁表 http://www.cnblogs.com/zfanlong1314/p/3698566.html http://www.cnblogs.com/chjf20 ...
- 获取select当前选择的值和文本
<html> <head> <script type="text/javascript"> function EE(obj) { alert(& ...
- OpenStack tokens id获取测试
- jquery的匿名函数研究
jQuery片段: ? 1 2 3 ( function (){ //这里忽略jQuery所有实现 })(); 半年前初次接触jQuery的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在 ...
- Class hierarchy of UIResponder as well as subclasses of UIView and UIControl
When you were dragging in your label and your button to this view, you were adding them as subviews. ...
- Oracle DB 使用调度程序自动执行任务
• 使用调度程序来简化管理任务 • 创建作业.程序和调度 • 监视作业执行 • 使用基于时间或基于事件的调度来执行调度程序作业 • 描述窗口.窗口组.作业类和使用者组的用途 • 使用电子邮件通知 • ...
- replace into
讨人喜欢的 MySQL replace into 用法(insert into 的增强版) 在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在: 2. 如果不存在,则插入:3.如果 ...
- PHP 自动生成导航网址的最佳方法 v20130826
经常制作开发不同的网站的后台,写过很多种不同的后台导航写法. 最终积累了这种最写法,算是最好的吧.附上截图和代码如下(PHP+HTML) <?php $linkArr = array( 'ind ...
- iOS开发——多线程OC篇&(十)多线程NSOperation基本使用
NSOperation基本操作 一.并发数 (1)并发数:同时执⾏行的任务数.比如,同时开3个线程执行3个任务,并发数就是3 (2)最大并发数:同一时间最多只能执行的任务的个数. (3)最⼤大并发数的 ...
- ios开发——实用技术篇Swift篇&拍照
拍照 // MARK: - 拍照 func fromPhotograph() { if UIImagePickerController.isSourceTypeAvailable(.Camera) { ...