【Java从0到架构师】SpringMVC - 返回值
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 - 返回值相关推荐
- 【Java从0到架构师】SpringBoot - SpringMVC
SpringBoot - SpringMVC SpringMVC 的配置 文件上传功能 文件下载 - 以附件形式下载 静态资源访问 静态资源访问 - 映射 静态资源访问 - webjars Java ...
- 【Java从0到架构师】SpringMVC - 异常处理_拦截器
异常处理_拦截器 异常处理 简单的异常与页面映射 - SimpleMappingExceptionResolver √自定义异常处理类 - 实现 HandlerExceptionResolver 接口 ...
- 【Java从0到架构师】SpringMVC - RESTful
RESTful RESTful 风格的实践建议 关于 put.delete @RestController Java 从 0 到架构师目录:[Java从0到架构师]学习记录 Gitee 代码:http ...
- 【Java从0到架构师】SpringMVC - 特殊的请求参数
SpringMVC - 特殊的请求参数 集合类型 - Map.List.Set.String[] Multipart 参数 - multipartResolver 文件参数 - MultipartFi ...
- 【Java从0到架构师】SpringMVC - 基础
SpringMVC - 基础 SpringMVC - 入门 web.xml 配置 DispatcherServlet appliactionContext.xml 新建 Controller Spri ...
- 【Java从0到架构师】项目实战 - 前后端分离、后端校验、Swagger、全局异常处理
项目实战 - 前后端分离.后端校验.Swagger Layui 同源策略 SpringMVC 实现 CORS 后端校验 - hibernate-validator 方法的 Model 参数校验 方法的 ...
- 【Java从0到架构师】SSM 整合(XML、纯注解)
SSM 整合 父子容器 父子容器的配置文件建议 子容器的加载创建 父容器的加载创建 MyBatis 补充 mybatis-config.xml Maven 补充 SSM 整合 - 纯注解 Initia ...
- 【Java从0到架构师(1),Java中高级面试题总结(全面)
JSP 九大内置对象 MySQL 基础 + 多表查询 [Java从0到架构师]MySQL 基础 MySQL MySQL 的使用步骤 数据库的内部存储细节 GUI 工具 SQL 语句 DDL 语句 DD ...
- 【Java从0到架构师】SpringCloud - Sleuth、Zipkin、Config
SpringCloud 链路追踪组件 Sleuth Zipkin 分布式配置中心 - Config Git + Config 分布式配置中心 Java 从 0 到架构师目录:[Java从0到架构师]学 ...
最新文章
- 混合密度网络(MDN)进行多元回归详解和代码示例
- 致客户的一封信:关于产品生命周期管理与高可用版本的提供
- c++语言中break的作用,C++ break和continue用法详解
- sealer背后实现整个集群一键交付的奥秘 | 龙蜥技术
- Java中的return this
- python堆模块_python内置堆模块
- 计算机指令要素,【计算机系统】CPU指令执行流程与指令流水线原理
- Modular multiplicative inverse 模逆元
- it有啥好咨询的_小经验 | 埃森哲Accenture管理咨询+IT咨询实习
- CPU读/写一个存储单元
- SQLServer数据通过sql插入GUID
- 实验楼与蓝桥网站合并 FAQ
- 基于JSP的小区停车管理系统设计与实现
- 手机12306买卧铺下铺技巧_12306网上购下铺技巧(亲历版)
- 软件质量管理体系 type:pdf_普宁iso14001环境管理体系AAA信用等级认证
- C++学习记录3:定义一个矩形类Rectangle
- 网络无法找到计算机6,手机可以搜到WiFi6路由器的信号,电脑却搜不到这是怎么回事?...
- Mac剪切快捷键使用技巧
- Springboot+mybatis
- 蓝桥杯 算法训练 幸运的店家