[TOC]
第一个SpringMVC框架
代码实现
创建Maven-webapp工程,pom.xml;
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.2.RELEASE</version> </dependency> </dependencies>
web.xml 添加拦截器
<servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
创建springmvc.xml (自动扫描不知道在哪个个包所以导入了全部)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 自动扫描--> <context:component-scan base-package="com.*"></context:component-scan> <!-- 视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
创建controller
package com.mvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HelloHandler { @RequestMapping("/index") public String index(){ System.out.println("进入了//"); return "index"; } }
Spring MVC注解
@RequestMapping
Sprng MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行映射,在Handler 的类定义处和方法处都可以添加 RequestMapping , 在类定义处添加,相当于客户端多了一层访问路径。
@Controller
@Controller 在类处定义添加,将该类交给 IoC 容器进行管理(结合 springmvc.xml 的自动扫描食用),同时将它成为一个控制器,可以接收客户端请求
package com.mvc.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloHandler {
@RequestMapping("/index")
public String index(){
System.out.println("进入了//");
return "index";
}
}
@RequestMapping 的相关参数
value
: 指定 URL 请求的实际地址, 是 @RequestMapping 的默认值。
@RequestMapping(value = "/index")
public String index(){
System.out.println("进入了//");
return "index";
}
method
:指定请求的类型,GET,POST,PUT,DELET;
@RequestMapping(value = "/test",method = RequestMethod.GET)
public String test(){
System.out.println("进入了//");
return "index";
}
上述代码只能接收GET请求;
params
: 指定请求必须包含某些参数,否则无法调用该方法;
@RequestMapping(value = "/test",method = RequestMethod.GET,params = {"name","id=10"})
public String test(String name,int id){
System.out.println(name);
System.out.println(id);
System.out.println("进入了//");
return "index";
}
以上表示 接收请求必须包含 name,id值,且id值必须等于10;
@PathVariable
: 传入的参数与实参不一致时,使用该方法绑定
@RequestMapping(value = "/test",method = RequestMethod.GET,params = {"name","id=10"})
public String test(@PathVariable("name") String qwq,@PathVariable("id") int qvq){
System.out.println(qwq);
System.out.println(qvq);
System.out.println("进入了//");
return "index";
}
Spring MVC 使用RESTful 风格的 URL;
传统类型: http://localhost:8080/aispringmvc_war/test?name=zhansan&id=10
REST : http://localhost:8080/aispringmvc_war/hello/test/ningling/15
@RequestMapping(value = "/test/{name}/{id}")
public String test(@PathVariable("name") String qwq,@PathVariable("id") int qvq){
System.out.println(qwq);
System.out.println(qvq);
System.out.println("进入了//");
return "index";
}
Spring MVC 数据绑定
数据绑定:在后端的业务方法中直接通过获取客户端HTTP请求中的参数,将请求参数映射到业务方法当中去,Spring MVC 中数据绑定的工作是由 HandlerAdpter 来完成的。
基本数据类型
@ResponseBody
@RequestMapping("/test")
public String test(int id){
System.out.println("进入test");
return ""+id;
}
发送请求 http://localhost:8080/aispringmvc_war/Date/test?id=18
当id值为null时会报错
包装类 Integer
@ResponseBody
@RequestMapping("/test")
public String test(Interg id){
System.out.println("进入test");
return ""+id;
}
发送请求 http://localhost:8080/aispringmvc_war/Date/test1?id=18
当id值为null时,返回页面显示null;
- @RequestParam
value = “num”:将HTTP 请求中名为 num 的参数赋给形参。
requried:设置 num 是否必须填写,true 表示必填,false 表示非必填,可省略。
defaultValue = “0”:如果HTTP 请求中没有 num 参数,默认值为0。
@ResponseBody
@RequestMapping("/test2")
public String test2(@RequestParam(value = "num",required = true,defaultValue = "10") Integer id){
System.out.println("进入test1");
return ""+id;
}
数据绑定 List
Spring MVC 不支持 LIst 类型的直接转换,需要对List 集合进行封装。
代码演示
集合封装类
package com.mvc.entity; import java.util.List; public class UserList { private List<User> UserList; }
jsp页面
<form action="date/list" method="post"> <input type="text" name="UserList[0].id"><br> <input type="text" name="UserList[0].name"><br> <input type="text" name="UserList[1].id"><br> <input type="text" name="UserList[1].name"><br> <input type="text" name="UserList[2].id"><br> <input type="text" name="UserList[2].name"><br> <input type="submit" value="提交"> </form>
controller 业务方法
@ResponseBody @RequestMapping(value = "/list",method = RequestMethod.POST) public String list(UserList list){ StringBuffer sb = new StringBuffer(); for (User u : list.getUserList()) sb.append(u.toString()); return sb.toString(); }
*绑定json对象
jsp页面引入 js,发送 json 请求
<script src="js/jquery-3.1.1.js"></script> <script> $(function () { alert("123"); var user = { "id":"1", "name":"张三" }; $.ajax({ url:"date/json", data:JSON.stringify(user), type:"POST", contentType:"applicaton/json;charset=UTF-8", dataType:"JSON", success:function (data) { alert(data.id+"-----"+data.name); } }) }) </script>
设置web.xml 过滤器,不拦截 js 请求
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping>
添加 fastjson 依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.32</version> </dependency>
springmvc.xml 配置fastjson
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <!-- 消息转换器,解决@ResponseBoyd 中文乱码--> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/> </bean> <!-- 配置fastjosn--> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4"/> </mvc:message-converters> </mvc:annotation-driven>
controller
@ResponseBody @RequestMapping("/json") public User json(User user){ System.out.println(user.toString()); user.setId(4); user.setName("狗子"); return user; }
Spring MVC 模型数据解析
JSP 四大作用域对象:爬个Content,request,session,application。
模型数据的绑定 是由 ViewResolver 完成的,实际开发中,需要先添加模型数据,再交个给 ViewResolver 来绑定。
Spring MVC 提供了以下几种方式添加模型数据:
- Map
- Model
- ModelAndView
- @ModolAttribute
- @SessionAttribute
代码演示
将模型数据存到 request中
1,Map
jsp 页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html> <head> <title>view</title> </head> <body> ${requestScope.user} </body> </html>
Controller
@RequestMapping("/map") public String map(Map map){ User user = new User(1,"张三",null); map.put("user",user); return "view"; }
2,Model
@RequestMapping("/model")
public String model(Model model){
User user = new User(1,"张三",null);
model.addAttribute("user",user);
return "view";
}
3,ModelAndView
@RequestMapping("/modelAttribute1")
public ModelAndView modelAttribute1(){
User user = new User(1,"张三",null);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("user",user);
modelAndView.setViewName("view");
return modelAndView;
}
@RequestMapping("/modelAttribute2")
public ModelAndView modelAttribute2(){
User user = new User(1,"张三",null);
ModelAndView modelAndView = new ModelAndView();
View view = new InternalResourceView("/view.jps");
modelAndView.addObject("user",user);
modelAndView.setView(view);
return modelAndView;
}
4,@ModelAttribute
@ModelAttribute
public User getUser(){
User user = new User(1,"张三",null);
return user;
}
@RequestMapping("/modelAttribute3")
public String modelAttribute3(){
return "view";
}
5, 原生方式 HttpServletRequest
@RequestMapping("/request")
public String request(HttpServletRequest request){
User user = new User(1,"张三",null);
request.setAttribute("user",user);
return "view";
}
将模型数据存入到 session 中
1,原生方式 HttpSession
@RequestMapping("/session")
public String session(HttpSession session){
User user = new User(1,"张三",null);
session.setAttribute("user",user);
return "view";
}
2,@SessionAttributes
当该类request 存入 “user” 时 自动存入 session 中
@SessionAttributes(value = "user") public class ConverterHandler { }
当该类 request 有 User 类时, 自动存入 session 中
@SessionAttributes(types = User.class) public class ConverterHandler { }
Spring MVC 自定义类型转换器
数据类型转换器是指客户端 HTTP 请求中的转换为业务方法中定义的行参。
自定义表示开发者可以自主设计转换的方式,HandlerApdter 已经提供了通用的转换(String转int,,String 转 double,表单的数据封装..)
但是在特殊的业务场景中,HandlerApdter无法进行转换,就需要开发者自行定义。
代码演示
创建Converter类实现Converter泛型接口
public class DateConverter implements Converter<String, Date> { private String pattern; public DateConverter(String pattern) { this.pattern = pattern; } @Override public Date convert(String source) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(this.pattern); Date date = null; try { date = simpleDateFormat.parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; } }
配置 springmvc.xml 添加转换器配置
<!--配置自定义转换器--> <bean id="conversinService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.mvc.converter.DateConverter"> <constructor-arg type="java.lang.String" value="yyyy-MM-dd"/> </bean> </list> </property> </bean> <mvc:annotation-driven conversion-service="conversinService"> <mvc:message-converters register-defaults="true"> <!-- 消息转换器,解决@ResponseBoyd 中文乱码--> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/> </bean> <!-- 配置fastjosn--> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4"/> </mvc:message-converters> </mvc:annotation-driven>
controller 层
@Controller @RequestMapping("/converter") public class ConverterHandler { @RequestMapping("/date") @ResponseBody public String Date(Date date){ return date.toString(); } }
jsp 发送请求
<body> <form action="converter/date" method="post"> <input type="text" name="date">yyyy-MM-dd<br/> <input type="submit" value="提交"> </form> </body>
Spring MVC REST
REST:Representational State Transfer,资源表现层状态转换,目前主流的一种互联网软件架构,它结构清晰,标准规范,易于理解,便于扩展。
- 资源(Resource)
网络上的一个实体,或者说网络中存在的一个具体信息,一段文本,一张图片,一首歌曲,一段视频等,总之就是一个具体的存在。可以用 URI (统一资源定位符)指向它,每个资源都有对应的一个特定的 URI,要获取该资源时,只需访问对应的 URI 即可。
- 表现层(Representation)
资源具体呈现出来的形式,比如文本可以用 txt 格式表示,也可以用 HTML,JSON 等格式来表示。
- 状态转换(State Transfer)
客户端如果希望操作服务器中的某一个资源,就需要通过某种方式让服务端发生状态转换,而这种转换是建立再表现层之上的,所以叫做“表现层状态转换”。
特点
URL 更加简洁
有利于不同系统之间的资源共享,只需遵守REST的规范,不需要进行其他配置即可实现资源共享。
如何使用
REST 具体操作就是HTTP 协议中四个表示操作方式的动词分别对应 CRUD 基本操作。
GET 用来获取资源。
POST 用来表示 新建资源。
PUT 用来修改资源。
DELETE 用来表示删除资源。
Spring MVC 文件上传下载
单文件上传
底层是通过 Apache fileupload 组件完成上传,Spring MVC 对这种方式进行了封装。
pom.xml
<!-- 文件上传依赖 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
controller
@RequestMapping("/file") @Controller public class UploadHandler { @RequestMapping("/upload") public String upload(MultipartFile img,HttpServletRequest request){ if (img.getSize() > 0){ //获取文件上传的路径 String path = request.getServletContext().getRealPath("file"); //获取上传的文件名 String name = img.getOriginalFilename(); File file = new File(path,name); try { img.transferTo(file); //上传 } catch (IOException e) { e.printStackTrace(); } request.setAttribute("path",name); //存到 request } return "upload"; } }
jsp
<body> <form action="file/upload" method="post" enctype="multipart/form-data"> <input type="file" name="img"><br/> <input type="submit" name="提交"> </form> <img src="${path}"> </body>
多文件下载
controller
@RequestMapping("/uploads") public String uploads(MultipartFile[] imgs,HttpServletRequest request){ List list = new ArrayList(); for (MultipartFile img:imgs) { if (img.getSize() > 0){ //获取文件上传的路径 String path = request.getServletContext().getRealPath("file"); //获取上传的文件名 String name = img.getOriginalFilename(); File file = new File(path,name); try { img.transferTo(file); //上传 list.add(name); //保存后的文件路径 } catch (IOException e) { e.printStackTrace(); } } } request.setAttribute("fileList",list); //存到 request return "upload"; }
jsp (再用jstl 遍历list)
<form action="file/uploads" method="post" enctype="multipart/form-data"> <input type="file" name="imgs"><br/> <input type="file" name="imgs"><br/> <input type="file" name="imgs"><br/> <input type="submit" name="提交"> </form>