SpringMVC的Controller返回各种视图

来源:互联网 发布:卡通睡衣品牌知乎 编辑:程序博客网 时间:2024/05/16 06:10

转载:原文链接


SpringMVC的Controller可以返回各种各样的视图,比如:
- jsp
- json
- velocity
- freeMarker
- xml
- pdf
- excel
- html

那么应该何如去处理呢?这里就涉及到了SpringMVC当中的视图解析器(viewResolver)。而上述的每一种视图(view)就对应了一种视图解析器。可以将视图解析器大致地分成两类:
1) 基于URL的视图解析器(UrlBasedViewResolver);
2) 其它解析器;

所谓的UrlBasedViewResolver,就是将返回值作为最终视图的URL的一部分,然后和相关配置组合起来,就是最终视图地址URL。

我们来看一下UrlBasedViewResolver的解析器有哪些:
1.返回JSP
返回JSP是最简单的一种,JSP视图的视图解析器对应为:InternalResourseViewResolver,也是一个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" />

最终得到:

"/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或者redirect到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中有多种处理方式:
1)使用SpringMVC自带的MappingJackson2JsonView来处理。
2)自己写代码将返回值JSON格式化,然后直接用PrintWriter类型的对象写出就行了。
3-1 直接用PrintWriter类型的对象写出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。
3-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>

这里用到了ContentNegotiatingResolver,“内容协商视图解析器”,其实就是根据返回什么类型的视图,就协商使用哪种视图解析器。如果返回jsp就使用InternalResorceViewResolver视图解析器,如果返回JSON格式就使用MappingJackson2JsonView来处理。在

<property name = "viewResolver">

下的

<list>

标签下,还可以加入其它各种视图的视图解析器的配置。
配置了MappingJackson2JsonView之后,就没有必要在自己手动JSON格式化了,上面的例子,可以改写成:

@RequiresRoles(value={"student"}) @RequestMapping(value="/queryScoreForStudent") @ResponseBody public Map<String, Object> queryScoreForStudent(ScoreQueryParam param, HttpSession sesion){    Map<String, Object> map = new HashMap<>();    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.put("result", "ok");         map.put("data", scoreList);     }     return map; }

其他格式Velocity, FreeMarker, XML, PDF, Excel等视图的处理,待补充。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 车被轻微刮花了怎么办 车被故意刮花了怎么办 车子自己刮花了怎么办 刚买的新车刮了怎么办 40周胎盘才一级怎么办 没感情了想离婚怎么办 对老公没感情了怎么办 和老公没感情了怎么办 跟老公没感情了怎么办 对老公感情淡了怎么办 和老公感情淡了怎么办 脖子又短又粗怎么办 18岁胸越来越小怎么办 觉得自己变丑了怎么办 我的皮肤很黑怎么办 喝老婆奶水会硬怎么办 真的很讨厌老公怎么办 老婆很讨厌我了怎么办 2岁泰迪牙齿掉了怎么办 4岁泰迪门牙掉了怎么办 种牙寿命结束后怎么办 后面的牙齿掉了怎么办 门牙齿掉了一颗怎么办 隆鼻后鼻头歪了怎么办 狗狗呕吐有虫子怎么办 狗狗呕吐出虫子怎么办 借债人无力还钱怎么办 微博被盗用了怎么办 我的眼袋很严重怎么办 怀孕了吐的很厉害怎么办 老婆怀孕吐的很厉害怎么办 孕妇6个月肚子疼怎么办 孕妇7个月肚子疼怎么办 辣椒吃多了胃疼怎么办 大腿内侧磨烂了怎么办 左脸腮帮子肿了怎么办 牙痛肿了半边脸怎么办 轮胎完全没气了怎么办 晚上车胎没气了怎么办 皇冠车胎没气了怎么办 娶了个懒老婆怎么办