第1章 ModelAttribute 和SessionAttribute[应用]
1.1 ModelAttribute
1.1.1 使用说明
1.1.2 使用示例
基于 POJO 属性的基本使用:
基于 Map 的应用场景示例 1: ModelAttribute 修饰方法带返回值
基于 Map 的应用场景示例 1: ModelAttribute 修饰方法不带返回值
1.2 SessionAttribute
1.2.1 使用说明
1.2.2 使用示例
tips SpringMvc匹配路径问题
不能写/*,因为/*目录匹配,一旦访问jsp页面,/*优先级高,DispatcherServlet没法处理,
写/同理,所以需要写放行路径,tomcat里两个默认servlet,jsp和default,在default里写
放行静态资源,jsp由专门servlet处理
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--
绝对不允许写/*
在tomcat匹配过程中
精确匹配 目录匹配 后缀名 /匹配
但是写/ 也出问题
然后去补上静态访问 添加给我默认servlet
-->
<servlet-mapping>
<!-- 所放行的类型 -->
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.png</url-pattern>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
第2章 Restful 风格的 URL[应用]
2.1 概述
2.1.1 什么是 rest:
REST(英文: Representational State Transfer,简称 REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种 Web 服务交互方案中, REST 相比于 SOAP(Simple Object Access protocol,简单对象访问协议)以及 XML-RPC 更加简单明了,无论是对 URL 的处理还是对 Payload 的编码, REST 都倾向于用更加简单轻量的方法设计和实现。值得注意的是 REST 并没有一个明确的标准,而更像是一种设计的风格。
它本身并没有什么实用性,其核心价值在于如何设计出符合 REST 风格的网络接口。
2.1.2 restful 的优点
它结构清晰、符合标准、易于理解、 扩展方便,所以正得到越来越多网站的采用。
2.2 PathVaribale 注解在 rest 风格 url 中的应用
2.2.1 使用说明
2.2.2 使用示例
2.3 基于 HiddentHttpMethodFilter 的示例
<!--
过滤器的作用
用来观察 你是携带了 名字叫做_method参数 根据你的需要将当前方式 改掉
-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<!-- 隐藏网站方法的过滤器 -->
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
实际案例
控制层
@Controller
public class UserController {
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
@ResponseBody
public User findById(@PathVariable("id") int id){
//mock查询
User user = new User();
user.setId(id);
user.setUsername("小j");
user.setPassword("123");
user.setAge(18);
return user;
}
@RequestMapping(value = "/user",method = RequestMethod.GET)
@ResponseBody
public List<Object> findAll(){
//mock查询
User user1 = new User();
user1.setId(1);
user1.setUsername("小h");
user1.setPassword("123");
user1.setAge(18);
User user2 = new User();
user2.setId(2);
user2.setUsername("小蓝");
user2.setPassword("123");
user2.setAge(18);
ArrayList<Object> users = new ArrayList<>();
users.add(user1);
users.add(user2);
return users;
}
@RequestMapping(value = "/user/{id}",method = RequestMethod.POST)
@ResponseBody
public String update(@PathVariable("id") int id,User user){
//mock更新
System.out.println(id);
System.out.println(user);
return "success";
}
@RequestMapping(value = "/user",method = RequestMethod.PUT)
@ResponseBody
public String save(User user){
//mock添加
System.out.println(user);
return "success";
}
@RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable("id") int id){
//mock添加
System.out.println(id);
return "success";
}
@RequestMapping("/user/{uid}/address/{aid}")
@ResponseBody
public String findUser4address(@PathVariable("aid") String aid,@PathVariable("uid") int uid){
System.out.println("收货地址id:"+aid);
System.out.println("用户id:"+uid);
return "success";
}
}
前端
<body>
<h3>更新操作</h3>
<form method="post" action="/user/2">
名字:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
年龄:<input type="text" name="age">
<input type="submit" value="点我提交表单">
</form>
<h3>put操作</h3>
<form method="post" action="/user">
<input type="hidden" name="_method" value="put">
名字:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
年龄:<input type="text" name="age">
<input type="submit" value="点我提交表单">
</form>
<h3>put操作</h3>
<form method="post" action="/user/1">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="点我提交表单">
</form>
</body>
最后总结
restful风格的url设计
传统的url设计
以用户操作为例
1.根据id查询
/user/findById?id=xxx
2.保存用户
/user/save
post请求发送 放在表单中
username=xx&password=xxx&age=18..
3.更新用户
/user/update
id=1&username=xxx&password=xxx
4.查询所有
/user/findAll
5.删除用户
/user/delete?id=xxx
restful风格:
以用户操作为例
1.根据id查询
路径 请求方式
/user/1 GET
2.保存用户
路径 请求方式
/user PUT
请求体数据
username=xx&password=xxx&age=18..
3.更新用户
路径 请求方式
/user/1 POST
数据还是这个
username=xxx&password=xxx
4.查询所有
路径 请求方式
/user GET
5.删除用户
路径 请求方式
user/1 DELETE
总结:
restful 传统方式比较起来就是 他把之前设计 动作在路径写着现在呢
把动作交给了 请求方式来做
get 获取
put 增加(更新)
post 更新(保存)
delete 删除
分页查询
/user/_page post
pageNumber=1
某个人某个收货地址
/user/2/shouhuo/asda3sdasgdj
第3章 控制器方法的返回值[掌握]
3.1 返回值分类
/**
* 某某个需求 不需要model
*
*
* 返回 视图 其实可以直接返回视图的地址字符串 没有必要非得 整个modelandview
* @return
*/
@RequestMapping("/test2")
public String test2(){
return "product/test";
}
/**
* 我们又想要返回 字符串 又需要数据
* 只用model
*
*/
@RequestMapping("/test3")
public String test3(Model model){
String s = new Date().toString();
model.addAttribute("content",s);
return "product/test";
}
3.2 转发和重定向
3.2.1 forward 转发
3.2.1 Redirect 重定向
/**
* 重定向操作方式一
* @return
*/
@RequestMapping("/test4")
public String test4(){
return "redirect:http://www.baidu.com";
}
/**
* 重定向操作方式二
* @return
*/
@RequestMapping("/test5")
public void test5(HttpServletResponse response) throws IOException {
response.sendRedirect("http://www.baidu.com");
}
第4章 交互 json 数据[应用]
4.1 返回值是对象json对象转换
导入maven坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
dispatcher-servlet.xml
<!--
指明requestMapping 现在版本 为了注入转换器
注入json 转化
-->
<mvc:annotation-driven>
<mvc:message-converters>
<!--
配置springmvc 相应内容的时候 麻烦你进行一下 jackson转换
-->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
</mvc:message-converters>
</mvc:annotation-driven>
传统方式
/**
* 返回任意对象 返回json格式给前端 传统的方式
* @return
*/
@RequestMapping("/test6")
public void test6(HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
//手写怎么玩
Product product = new Product();
product.setId(1);
product.setPname("小米手机");
product.setPrice(2999.99);
ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writeValueAsString(product);
response.getWriter().println(s);
}
ReponseBody方式
能转json格式就会转json返回,转不了string格式返回
@RequestMapping("/test7")
@ResponseBody
public Product test7(HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
//手写怎么玩
Product product = new Product();
product.setId(1);
product.setPname("小米手机");
product.setPrice(2999.99);
return product;
}
@RequestMapping("/test8")
@ResponseBody
public String test8(HttpServletResponse response) throws IOException {
return "xixihaha";
}
4.2 前端发送json格式数据后端封装采用
@RequestBody使用
contentType:"application/json;charset=utf-8"设置类型json格式
前端页面
<script src="../js/jquery.min.js"></script>
<script>
function req(){
//var s={"id":1,"pname":"锤子手机","price":2000};
//发请求
$.ajax({
url:"/product/test9",
type:"post",
data:"{\"id\":1,\"pname\":\"锤子手机\",\"price\":2000}",
contentType:"application/json;charset=utf-8",
success:function(data){
alert(data);
}
})
}
</script>
</head>
<body>
我是一个静态页面
<input type="button" value="点我发送ajax请求参数json格式的字符串" onclick="req()">
</body>
后端
/**
*
* 前端传数据 传json格式的数据
*
* 后端需要封装对象的时候 请你 使用 @requestBody springmvc 自动按照json格式给你转换对象
* 如果不使用@requestBody,默认request.getParamter方式获取,获取json获取不到,
* 以json格式封装到Product对象里
* @return
* @throws IOException
*/
@RequestMapping("/test9")
@ResponseBody
public String test9(@RequestBody Product product, Model model) throws IOException {
System.out.println(product);
String s = new Date().toString();
model.addAttribute("content",s);
return "success";
}
第5章 SpringMVC 实现文件上传[应用]
5.1 文件上传的回顾
5.1.1 文件上传的必要前提
A form 表单的 enctype 取值必须是: multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型
B method 属性取值必须是 Post
C 提供一个文件选择域<input type=”file” />
5.1.2 文件上传的原理分析
5.1.3 借助第三方组件实现文件上传
5.2 springmvc 传统方式的文件上传
5.2.1 说明
传统方式的文件上传, 指的是我们上传的文件和访问的应用存在于同一台服务器上。
并且上传完成之后,浏览器可能跳转
5.2.2 实现步骤
5.2.2.1 第一步: 创建 maven 工程并导入 commons-fileupload 坐标
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
5.2.2.2 第二步:编写 jsp 页面
5.2.2.3 第三步:编写控制器
自己写的控制器
@Controller
public class UploadController {
/*
* MultipartFile 就是springmvc 给我们封装好文件对象 参数名字 必须input输入框的 name属性一致
* */
@RequestMapping("/upload")
@ResponseBody
public String upload(MultipartFile avatar) throws IOException {
//以前写 你会在这里使用 apache提供文件上传解析包 自己一点点解释出来
String contentType = avatar.getContentType();
System.out.println("文件类型:"+contentType);
String name = avatar.getName();
System.out.println("代表是你参数 name属性值:"+name);
String originalFilename = avatar.getOriginalFilename();
System.out.println("原本的文件名:"+originalFilename);
InputStream inputStream = avatar.getInputStream();
FileOutputStream outputStream = new FileOutputStream("/Users/huyoufu/" + originalFilename);
IOUtils.copy(inputStream,outputStream);
outputStream.close();
inputStream.close();
return "success";
}
}
5.2.2.4 第四步:配置文件解析器
5.3 springmvc 跨服务器方式的文件上传
5.3.1 分服务器的目的
5.3.2 准备两个 tomcat 服务器,并创建一个用于存放图片的 web 工程
5.3.3 导入 jersey 的坐标
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
5.3.4 编写控制器实现上传图片
5.3.5 编写 jsp 页面
5.3.6 配置解析器
第6章 SpringMVC 中的异常处理[理解]
6.1异常处理的思路
系统中异常包括两类:预期异常和运行时异常 RuntimeException,前者通过捕获异常从而获取异常信息,
后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
系统的 dao、 service、 controller 出现都通过 throws Exception 向上抛出,最后由 springmvc 前端
控制器交由异常处理器进行异常处理,如下图:
6.2实现步骤
6.2.1 编写异常类和错误页面
6.2.2 自定义异常处理器
6.2.3 配置异常处理器
6.2.4 运行结果:
自己的实例
MyExceptionResolver.java
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView = new ModelAndView();
if (ex instanceof MyException1){
MyException1 exception1= (MyException1) ex;
modelAndView.addObject("code",exception1.getCode());
modelAndView.addObject("msg",exception1.getDesc());
}else if(ex instanceof MyException2){
MyException2 exception2= (MyException2) ex;
modelAndView.addObject("code",exception2.getCode());
modelAndView.addObject("msg",exception2.getDesc());
}else{
modelAndView.addObject("code","10001");
modelAndView.addObject("msg","系统异常");
}
modelAndView.setViewName("error/beautiful");
return modelAndView;
}
}