SpringMVC - 返回值

  • controller 中的返回值
    • 无返回值 - 使用原始的 Servlet 的方法
    • 普通文本、HTML - 设置响应头 Content-Type
    • XML - 推荐使用 jaxb
    • JSON - 框架中已经集成 jackson
  • jsp 相关
    • 转发 - ModelAndView、String
    • 路径问题总结(Java、Html)
    • 重定向 - "redirect:"
    • mvc:view-controller - 配置请求路径和 viewName
    • InternalResourceViewResolver - 设置视图的公共前缀、后缀
      • 忽略 InternalResourceViewResolver
      • 自定义 InternalResourceViewResolver
    • @ResponseStatus - 设置响应码

Java 从 0 到架构师目录:【Java从0到架构师】学习记录

Gitee 代码:https://gitee.com/szluyu99/mj_java_frame/tree/master/03_SpringMVC

controller 中的返回值

无返回值 - 使用原始的 Servlet 的方法

如果返回值为 void,则和以前操作 Servlet 的方式相同,使用 response 完成相关操作

@RequestMapping("/void")
public void testVoid(HttpServletRequest request,HttpServletResponse response) throws Exception {response.setContentType("text/html; charset=UTF-8");response.getWriter().write("MJ666");
}

普通文本、HTML - 设置响应头 Content-Type

主要是利用 @RequestMapping 的 produces 属性,本质上是设置响应头 Content-Type

@RequestMapping(value = "/plainText",produces = "text/plain; charset=UTF-8"
)
@ResponseBody
public String plainText() {return "this is plainText";
}
@RequestMapping(value = "/html",produces = "html/plain; charset=UTF-8"
)
@ResponseBody
public String html() {return "<h1>This is MJ</h1>";
}

XML - 推荐使用 jaxb

方法1(不推荐):直接返回字符串拼接的 XML

以上方法的本质是返回值为 String 字符串,因此解决乱码问题在 @RequestMapping 中设置即可


方法2(推荐):利用 jaxb 将 Model 对象转为 XML

jaxb 与 SpringMVC 集成的很好,推荐使用

<!-- Model转XML字符串 -->
<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.4.0-b180830.0359</version>
</dependency><dependency><groupId>javax.xml</groupId><artifactId>jaxb-impl</artifactId><version>2.1</version>
</dependency>

必须使用 <mvc:annotation-driven>

使用 @XmlRootElement@XmlElement@XmlAttribute 标识如何将 Model 转为 XML

在控制器中返回 Model 对象,会自动转为 XML 格式的数据:

利用该方法,要解决乱码问题,需要通过 Jaxb2RootElementHttpMessageConverter 设置编码

<mvc:annotation-driven><mvc:message-converters><!-- 影响返回值是Model对象(最后通过JAXB转成XML字符串) --><bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"><property name="defaultCharset" value="UTF-8"/></bean></mvc:message-converters>
</mvc:annotation-driven>

JSON - 框架中已经集成 jackson

方法1(不推荐):直接返回字符串拼接的 JSON

方法2(推荐):使用 Jackson(SpringMVC 中已经集成,只需要引入依赖即可启用)

<!-- Model转JSON字符串 -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.0</version>
</dependency>

在 Maven 中引入依赖后,在 controller 中返回的 Model 对象就会自动转成 JSON 格式

@RequestMapping("/json2")
@ResponseBody
public Student json() {Student student = new Student();student.setAge(20);student.setName("MJ");return Student;
}

利用该方法,要解决乱码问题,需要通过 MappingJackson2HttpMessageConverter 设置编码

<mvc:annotation-driven><mvc:message-converters><!-- 影响返回值是Model对象(最后通过Jackson转成JSON字符串) --><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="defaultCharset" value="UTF-8"/></bean></mvc:message-converters>
</mvc:annotation-driven>

jsp 相关

转发 - ModelAndView、String

可以利用 ModelAndView 将数据和视图绑定到一起,返回给客户端

@RequestMapping("/mv1")
public ModelAndView mv1(){// 创建ModelAndView并设置要转发的页面ModelAndView mv = new ModelAndView("/person.jsp");// mv.setViewName("/page/jsp1.jsp"); // 也可以这么写Person person = new Person("MJ", 20);request.setAttribute("person", person);// 本质就是request.setAttribute()mv.addObject("person", person);return mv;
}

不加 @ResponseBody 的 String 返回值,也代表 viewName

@RequestMapping("/mv3")
public ModelAndView mv3(){    Person person = new Person("MJ", 20);request.setAttribute("person", person);return "/jsp3.jsp";
}

路径问题总结(Java、Html)

思考:前面的代码中将 /person.jsp 改成 person.jsp 结果会有什么不同?

在 Java 代码中,路径问题总结:

1.假设请求路径是:"http://IP地址:端口/context_path/path1/path2/path3"
2.假设转发路径是:"/page/test.jsp"1> 以斜线(/)开头,参考路径是context_path2> 所以最终转发路径是:"http://IP地址:端口/context_path" + "/page/test.jsp"
3.假设转发路径是:"page/test.jsp"1> 不以斜线(/)开头,参考路径是当前请求路径的上一层路径2> 所以最终转发路径是:"http://IP地址:端口/context_path/path1/path2/" + "page/test.jsp"

在 jsp、html 代码中,路径问题总结:

1.假设请求路径是:"http://IP地址:端口/context_path/path1/path2/path3"
2.假设跳转路径是:"/page/test.jsp"1> 以斜线(/)开头,参考路径是"http://IP地址:端口"2> 所以最终转发路径是:"http://IP地址:端口" + "/page/test.jsp"

重定向 - “redirect:”

在 viewName 前面加上 "redirect:" 表示重定向

通过返回 String 进行重定向:

@RequestMapping("/jsp3")
public String jsp3(){return "redirect:/page/person.jsp";
}

通过 ModelAndView 进行重定向:

@RequestMapping("/jsp4")
public ModelAndView jsp4(){ModelAndView mv = new ModelAndView();// 设置数据mv.addObject("name", "Jack");mv.addObject("price", 666);// 设置页面mv.setViewName("redirect:/page/jsp4.jsp?test=10");return mv;
}

参考源码:org.springframework.web.servlet.view.UrlBasedViewResolver

SpringMVC 默认会将 ModelAndView 对象 addObject 的内容,通过请求参数的形式传递给重定向的页面

一些简单的数据(String、int 等)会自动转化为请求参数,像 Model 对象无法直接作为请求参数

  • 在重定向的页面中可以通过 request.getParameter${param]} 获取请求参数

mvc:view-controller - 配置请求路径和 viewName

可以使用 <mvc:view-controller> 直接配置请求路径和 viewName

<mvc:view-controller path="/mv5" view-name="/person.jsp" />
  • 当没有 controller 处理这个 path 时,才会交给 <mvc:view-controller> 去处理

使用了 <mvc:view-controller> 后,需要加上 <mvc:annotation-drive>

  • 否则会导致 controller 无法处理请求

InternalResourceViewResolver - 设置视图的公共前缀、后缀

可以通过 InternalResourceViewResolver 设置视图路径的公共前缀、后缀

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 前缀 --><property name="prefix" value="/WEB-INF/page/"/><!-- 后缀 --><property name="suffix" value=".jsp"/>
</bean>

受 InternalResourceViewResolver 影响的有:

  • 通过返回值 ModelAndView 设置的 viewName
  • 通过返回值 String 设置的 viewName
  • 通过 <mvc:view-controller> 设置的 viewName

可以配置多个 InternalResourceViewResolver,order 越小,优先级越高

注意,并不是从优先级高的开始依次往后找,优先级最高的那个找不到就不会再去找其他

  • 解决方案是自定义 InternalResourceViewResolver(后面有)
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- order越小,优先级越高 --><property name="order" value="0"/><!-- 前缀 --><property name="prefix" value="/WEB-INF/page/"/><!-- 后缀 --><property name="suffix" value=".jsp"/>
</bean>

忽略 InternalResourceViewResolver

有的时候配置了公共前缀、后缀,但是某个视图希望不使用该后缀,解决方案:

  • 方法1:在 viewName 前面加上 "forward:""redirect:"
  • 方法2:通过 ModelAndView 的 setView 方法
// 转发
view.setView(new InternalResourceView("/person.jsp"));
view.setView(new JstlView("/person.jsp"));
// 重定向
view.setView(new RedirectView("/person.jsp"));

实际上,之前通过返回值 String、ModelAndView 设置 viewName 之后

  • SpringMVC 内部会根据具体情况创建对应的 View 对象
    InternalResourceView、JstlView、RedirectView

InternalResourceViewResolver 影响的是:没有带 "forward:"redirect: 的 viewName

自定义 InternalResourceViewResolver

自定义 InternalResourceViewResolver 主要是重写:checkResource 方法,因为源码中该方法必然返回 True,哪怕找不到资源也会返回 True,所以哪怕配置多个 InternalResourceViewResolver 并通过 order 指定优先级,也只会执行优先级最高的然后直接返回 True

通过自定义 InternalResourceViewResolver,可以实现:

  • 当一个 InternalResourceViewResolver 拼接的路径找不到时
  • 就尝试下一个 order 比较大的 InternalResourceViewResolver
public class MyView extends InternalResourceView {@Overridepublic boolean checkResource(Locale locale) throws Exception {// 根据实际情况来返回// 存在, 返回true// 不存在, 返回false// 项目部署的根路径 + /page/index.jsp// String path = getServletContext().getRealPath("/") + getUrl();String path = getServletContext().getRealPath(getUrl());File file = new File(path);return file.exists();}
}
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 自定义InternalResourceViewResolver,没有找到资源则执行其他 --><property name="viewClass" value="com.mj.view.MyView"/><property name="prefix" value="/WEB-INF/page/"/><property name="suffix" value=".jsp"/><property name="order" value="0"/>
</bean><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 最后一次还是需要交由默认处理,无论实际资源是否存在都返回True --><property name="order" value="1"/><property name="prefix" value="/WEB-INF/other/"/><property name="suffix" value=".jsp"/>
</bean>

@ResponseStatus - 设置响应码

可以通过 @ResponseStatus 设置响应码

@RequestMapping("/test1")
@ResponseStatus(value = HttpStatus.BAD_REQUEST,reason = "你这个错误666啊"
)
public String test1() throws Exception {return "/index.jsp";
}

【Java从0到架构师】SpringMVC - 返回值相关推荐

  1. 【Java从0到架构师】SpringBoot - SpringMVC

    SpringBoot - SpringMVC SpringMVC 的配置 文件上传功能 文件下载 - 以附件形式下载 静态资源访问 静态资源访问 - 映射 静态资源访问 - webjars Java ...

  2. 【Java从0到架构师】SpringMVC - 异常处理_拦截器

    异常处理_拦截器 异常处理 简单的异常与页面映射 - SimpleMappingExceptionResolver √自定义异常处理类 - 实现 HandlerExceptionResolver 接口 ...

  3. 【Java从0到架构师】SpringMVC - RESTful

    RESTful RESTful 风格的实践建议 关于 put.delete @RestController Java 从 0 到架构师目录:[Java从0到架构师]学习记录 Gitee 代码:http ...

  4. 【Java从0到架构师】SpringMVC - 特殊的请求参数

    SpringMVC - 特殊的请求参数 集合类型 - Map.List.Set.String[] Multipart 参数 - multipartResolver 文件参数 - MultipartFi ...

  5. 【Java从0到架构师】SpringMVC - 基础

    SpringMVC - 基础 SpringMVC - 入门 web.xml 配置 DispatcherServlet appliactionContext.xml 新建 Controller Spri ...

  6. 【Java从0到架构师】项目实战 - 前后端分离、后端校验、Swagger、全局异常处理

    项目实战 - 前后端分离.后端校验.Swagger Layui 同源策略 SpringMVC 实现 CORS 后端校验 - hibernate-validator 方法的 Model 参数校验 方法的 ...

  7. 【Java从0到架构师】SSM 整合(XML、纯注解)

    SSM 整合 父子容器 父子容器的配置文件建议 子容器的加载创建 父容器的加载创建 MyBatis 补充 mybatis-config.xml Maven 补充 SSM 整合 - 纯注解 Initia ...

  8. 【Java从0到架构师(1),Java中高级面试题总结(全面)

    JSP 九大内置对象 MySQL 基础 + 多表查询 [Java从0到架构师]MySQL 基础 MySQL MySQL 的使用步骤 数据库的内部存储细节 GUI 工具 SQL 语句 DDL 语句 DD ...

  9. 【Java从0到架构师】SpringCloud - Sleuth、Zipkin、Config

    SpringCloud 链路追踪组件 Sleuth Zipkin 分布式配置中心 - Config Git + Config 分布式配置中心 Java 从 0 到架构师目录:[Java从0到架构师]学 ...

最新文章

  1. 混合密度网络(MDN)进行多元回归详解和代码示例
  2. 致客户的一封信:关于产品生命周期管理与高可用版本的提供
  3. c++语言中break的作用,C++ break和continue用法详解
  4. sealer背后实现整个集群一键交付的奥秘 | 龙蜥技术
  5. Java中的return this
  6. python堆模块_python内置堆模块
  7. 计算机指令要素,【计算机系统】CPU指令执行流程与指令流水线原理
  8. Modular multiplicative inverse 模逆元
  9. it有啥好咨询的_小经验 | 埃森哲Accenture管理咨询+IT咨询实习
  10. CPU读/写一个存储单元
  11. SQLServer数据通过sql插入GUID
  12. 实验楼与蓝桥网站合并 FAQ
  13. 基于JSP的小区停车管理系统设计与实现
  14. 手机12306买卧铺下铺技巧_12306网上购下铺技巧(亲历版)
  15. 软件质量管理体系 type:pdf_普宁iso14001环境管理体系AAA信用等级认证
  16. C++学习记录3:定义一个矩形类Rectangle
  17. 网络无法找到计算机6,手机可以搜到WiFi6路由器的信号,电脑却搜不到这是怎么回事?...
  18. Mac剪切快捷键使用技巧
  19. Springboot+mybatis
  20. 蓝桥杯 算法训练 幸运的店家

热门文章

  1. 经销商生意平台化是趋势
  2. 区块链开发入门书籍和文档
  3. 将pandas中Dataframe数据转换为二维数组array
  4. 计算机网络class5(分层结构、协议、接口、服务)
  5. 逻辑SQL Server数据复制101
  6. 201671010430 司昕劼 实验十四 课程学习总结
  7. 多个div中的label标签对齐
  8. Android 6.0权限分组
  9. Visual Studio Code 使用Git进行版本控制
  10. What is Dark Net