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使用IP无法连接的问题,用localhost或者‘“.”可以连接
今天装了一个mssql发现用ip无法连接但是用localhost和“.”却可以连接,纠结了一天终于找到了问题的解决办法: 打开mssql配置管理器(我点电脑---->右键选择管理--->服 ...
- springMVC+JAP整合彻底摆脱persistence.xml配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- Mysql自增字段
1.关键字 auto_increment 2.自增用法 例: CREATE TABLE animals ( id mediumint not null auto_increment, name cha ...
- 结构类模式(三):组合(Composite)
定义 将对象组合成树形结构以表示“部分整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客 ...
- jquery操作select 的value和text值
获取select 的text值: $('#testSelect option:selected').text(); 获取select 的value值: $('#testSelect').val(); ...
- Release 版本和 Debug 版本
什么是 Release 版本.Debug 版本? bug-缺陷,程序故障.而debug指的是排除缺陷,显然这个模式是面向开发者的. 而release是满足发布所用. Debug 和 Release,在 ...
- 转载:js和as间的交互
转载一: 提及AS3与外部脚本的交互,笔者认为可以总结成两种.一是AS3调用外部函数,二是外部脚本调用AS3函数.无外乎就 这两种.在调用函数的同时,我们还可以向函数传递一些参数.这就达到了传递数据的 ...
- sql server2008评估期已过...问题
sql server2008评估期已过...问题 当打开sql server2008企业管理器的时候,出现报错“评估期已过.有关如何升级的测试版软件的信息.....” 工具/原料 sql serv ...
- Correct thread terminate and destroy
http://www.techques.com/question/1-3788743/Correct-thread-destroy Hello At my form I create TFrame a ...
- 查看sid
查看用户sid: whoami /user 查看系统sid: 使用PSTools工具中的 psgetsid.exe命令查看