简介:
简介:什么是spring-mvc
Spring-MVC是Spring框架中的一个模块,用于构建基于MVC设计模式的Web应用。它分离了应用程序的业务逻辑,用户界面,和输入控制,使开发更加模块化和易于维护。
Spring_MVC是web框架,作用在表述层。帮助我们接收前端的请求
**最终总结:作用**
1. 简化前端参数接收( 形参列表 )
2. 简化后端数据响应(返回值)
内部流程:
Spring-MVC内部封装的使一个Servlet(DispactcherServlet)--------------------所有的请求都会到该Servlet
Spring-MVC内部还有一个handlerMapping组件会保存我们对应的方法的路径
Spring-MVC内部还有一个handlerAdapter(适配器)----------------简化参数处理将原始的参数转成handler需要的参数
---------------简化数据响应,将handler返回的数据封装到response
Spring-MVC内部还有一个视图解析器----------------帮助我们查找视图(设置前缀和后缀,将返回的数据拼接,最终找到需要的视图)
组件:
①DispactcherServlet 处理全部请求
②handlerMapping 缓存handler地址和方法
③handlerAdapter(适配器) 参数和响应简化
④视图解析器(查找视图页面) 简化视图查找
基本体验
contorller层定义方法:
@Controller
/**
* 步骤:
* 将该controller类的对象加入到ioc容器中
* 定义要访问的方法,定义方法的访问地址 ----------使用@RequestMapping("方法的地址")
* 若方法没有要访问的视图----------使用@ResponseBody直接返回字符串给前端,不要找视图解析器
*/
public class HelloController {
//handler 地址为springmvc/hello return "hello springmvc!!"
@RequestMapping("springmvc/hello")//对外访问的地址 到handlerMapping注册的注解
@ResponseBody//直接返回字符串给前端,不要找视图解析器
//handler(一个方法就对应一个handler) 地址为springmvc/hello return "hello springmvc!!"
public String hello(){
System.out.println("hello springmvc!!");
return "hello springmvc!!";
}
}
配置类
/**
* 1将contorller配置到ioc容器
* 2handlerMapping handlerAdapter加入到ioc容器
**/
//TODO: SpringMVC对应组件的配置类 [声明SpringMVC需要的组件信息]
//TODO: 导入handlerMapping和handlerAdapter的三种方式
//1.自动导入handlerMapping和handlerAdapter [推荐]
//2.可以不添加,springmvc会检查是否配置handlerMapping和handlerAdapter,没有配置默认加载
//3.使用@Bean方式配置handlerMapper和handlerAdapter
@EnableWebMvc
@Configuration-------------------组件注解
@ComponentScan(basePackages = "com.atguigu.controller") //TODO: 进行controller扫描
//WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
public class SpringMvcConfig implements WebMvcConfigurer {
@Bean
public HandlerMapping handlerMapping(){
return new RequestMappingHandlerMapping();
}
@Bean
public HandlerAdapter handlerAdapter(){
return new RequestMappingHandlerAdapter();
}
}
Spring-MVC环境搭建
//TODO: SpringMVC提供的接口,是替代web.xml的方案,更方便实现完全注解方式ssm处理!
//TODO: Springmvc框架会自动检查当前类的实现类,会自动加载 getRootConfigClasses / getServletConfigClasses 提供的配置类
//TODO: getServletMappings 返回的地址 设置DispatherServlet对应处理的地址
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 指定service / mapper层的配置类
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
/**
* 指定springmvc的配置类
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { MvcConfig.class };
}
/**
* 设置dispatcherServlet的处理路径!
* 一般情况下为 / 代表处理所有请求!
*/
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
接收数据
路径设置注解
@RequestMapping注解的作用就是将请求的 URL 地址和处理请求的方式(handler方法)关联起来,建立映射关系。
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的方法来处理这个请求。
* 注意:
* @WebServlet("必须使用/开头")
* @RequestMapping("没有要求/开头")
* 1精准地址【一个/多个】 /user/login {"地址1","地址2"}
* 2支持模糊地址 *代表任意一层字符串 **代表任意层任意字符串
* 3类上和方法上添加 @RequestMapping 的区别
* 类上提取通用的访问地址
* 方法上使具体的handler地址
* 访问:类地址+方法地址
* 特殊情况:如果类上设置了地址,而方法上只添加了一个@RequestMapping,没有写地址,那么该方法直接使用类的地址。
* 4 请求方式指定
* 前端通过http协议向后端发起请求,请求协议有许多请求方式(get/post/put/delete)
* 默认情况: @RequestMapping("register")主要地址正确,任何请求方式都可以访问
* 指定请求方式:method = {RequestMethod.GET,RequestMethod.POST,...}
* 当请求不符合请求方式时,会包405的错误
* 5 注解进阶 只能用在方法上
* get请求 @CetMapping == @RequestMapping(xxx,method=GET)
* post请求 @PostMapping == @RequestMapping(xxx,method=POST)
* put请求 @PUTMapping == @RequestMapping(xxx,method=PUT)
* delete请求 @PostMapping == @RequestMapping(xxx,method=DELETE)
代码举例:
@RequestMapping("/user")
public class UserController {
//特殊情况
@RequestMapping//方法上没有写地址,就直接使用类的地址,故其地址为“/user”
public String index(){
return null;
}
@RequestMapping(value = "login",method = RequestMethod.POST)
//注册地址 将handler注册到handlerMapping中(将方法的地址存入到handlerMapping中)
public String login(){
return null;
}
@RequestMapping(value = "register",method = {RequestMethod.GET,RequestMethod.POST})
public String register(){
return null;
}
对比json和param
前端传递参数一般有两种形式
Param key=value & key=value
JSON {key:value,key:value}
区别
1. 参数编码:
param 类型的参数会被编码为 ASCII 码。例如,假设 `name=john doe`,则会被编码为 `name=john%20doe`。而 JSON 类型的参数会被编码为 UTF-8
2. 参数顺序:
param 类型的参数没有顺序限制。但是,JSON 类型的参数是有序的。JSON 采用键值对的形式进行传递,其中键值对是有序排列的。
3. 数据类型:
param 类型的参数仅支持字符串类型、数值类型和布尔类型等简单数据类型。而 JSON 类型的参数则支持更复杂的数据类型,如数组、对象等。
4. 嵌套性:
param 类型的参数不支持嵌套。但是,JSON 类型的参数支持嵌套,可以传递更为复杂的数据结构。
5. 可读性:
param 类型的参数格式比 JSON 类型的参数更加简单、易读。但是,JSON 格式在传递嵌套数据结构时更加清晰易懂。
总的来说,param 类型的参数适用于单一的数据传递,而 JSON 类型的参数则更适用于更复杂的数据结构传递。根据具体的业务需求,需要选择合适的参数类型。在实际开发中,常见的做法是:在 GET 请求中采用 param 类型的参数,而在 POST 请求中采用 JSON 类型的参数传递。
param参数接收四种场景
@Controller
@RequestMapping("param")
public class ParaController {
/**
* 直接接收
* param/data?name=root&age=18
* 形参列表填对应的形参名即可!请求参数名 = 形参参数名即可
* 1 名称相同 2 可以不传递,不会报错
*/
@RequestMapping("/data")
@ResponseBody//一定要加上不然会包404错误
public String data(String name,int age){
System.out.println("name = " + name + ", age = " + age);
return "name = " + name + ", age = " + age;
}
/**
* param/data1?account=root
* 注解指定-------------在形参前加上@RequestParam注解
* 可以指定任意的请求参数名------------@RequestParam中的value属性
* 可以要求必须传递,可以要求不必须传递,---------------属性required默认是true(必须传递,如果不传会报400)
* 可以指定默认值----------------defaultValue="默认值"(单当设置为非必须传递时)
*/
@RequestMapping("data1")
@ResponseBody
public String data1(@RequestParam(value = "account") String name,
@RequestParam(required = false,defaultValue = "1") int page){
System.out.println("name = " + name + ", page = " + page);
return "name = " + name + ", page = " + page;
}
/**
* 特殊值
* 一名多值 key=1&key=2 ------------直接使用集合接值即可
* param/data2?hbs=吃&hbs=喝&hbs=玩
*注意点:
* 当以集合接值时不使用@RequestParam 会报类型异常
* 使用@RequestParam时,会将参数对应的值赋值给集合
*/
@RequestMapping("data2")
@ResponseBody
public String data2(@RequestParam List<String> hbs){
System.out.println("hbs = " + hbs);
return "ok";
}
/**
* 使用实体对象接值(重点)
* 因为传入的数据最终会被添加到数据库表(每一行数据都对应一个对象,所以直接用对象接值会更具容易地向数据库中添加数据)
* param/data3?name=二狗子&age=19
* 步骤:
* ①准备一个对应属性和get|set方法的实体类即可
* ②形参列表声明对象参数即可
* 注意:实体类的属性名一定要等于对应的传入参数的key
*/
@RequestMapping("data3")
@ResponseBody
public String data3(User user){
System.out.println("user = " + user);
return "user = " + user;
}
}
路径参数接收
路径传递参数是一种在 URL 路径中传递参数的方式。在 RESTful 的 Web 应用程序中,经常使用路径传递参数来表示资源的唯一标识符或更复杂的表示方式。而 Spring MVC 框架提供了 `@PathVariable` 注解来处理路径传递参数。
`@PathVariable` 注解允许将 URL 中的占位符映射到控制器方法中的参数。
例如,如果我们想将 `/user/{id}` 路径下的 `{id}` 映射到控制器方法的一个参数中,则可以使用 `@PathVariable` 注解来实现。
/**
* 路径参数接收
* path/账号/密码
* 动态路径设计 @RequestMapping("{参数名1}/{参数名2}") {key} 在形参列表获取传入的参数
* 接收路径参数
* String username, String password--》默认接收parameter格式的参数而非路径参数
* @PathVariable String account,@PathVariable String password--》接收路径参数
步骤:
①动态声明路径
②使用@PathVariable来指定接收路径参数
*/
@RequestMapping("{account}/{password}")
@ResponseBody
public String login(@PathVariable("account") String username,@PathVariable String password){
System.out.println("username = " + username + ", password = " + password);
return "username = " + username + ", password = " + password;
}
json数据接收
注意:json数据的发送需要用到post方式
@Controller
@RequestMapping("json")
@ResponseBody
public class JsonController {
/**
* 数据是以past请求方式传递过来的json数据{name,age,gender}---------------存在与请求体中
* 注意:
* ①访问方法的路径使用@PostMapping注解设置
* ②形参使用@RequestBody修饰 -------- 表示接收json数据
*/
@PostMapping("data")
public String data(@RequestBody Person person){
System.out.println("person = " + person);
return "person = " + person;
}
/**
* 前端发送来了一个json格式的数据,报415错误
* 原因:Java原生的api只支持路径参数和param参数 request.getParameter("key");param不支持json
* 解决:
* ①导入json依赖
* ②在配置类上加上 @EnableWebMvc//相当与给handlerAdapter配置了json转换器
*/
@EnableWebMvc注解原理
作用:添加handlerMapping与handlerAdapter,并给handlerAdapter添加json处理器
所以在配置类上加上@EnableWebMvc注解后就不用再配置类中手动添加handlerMapping与 handlerAdapter到ioc容器了
接收Cookie
/**
* 接收cookie--------------再形参前加上@CookieValue(value = "cookie的名字")
*
* 添加cookie:
* 是向response中添加cookie
* new一个cookie,传入cookie的名字与值
* 通过response调用addCookie()传入cookie
*/
@Controller
@RequestMapping("cookie")
@ResponseBody
public class CookieController {
//取cookie
@RequestMapping("data")
public String data(@CookieValue(value = "cookieName") String value){
System.out.println("value = " + value);
return value;
}
//存一个cookie
@GetMapping("save")
public String save(HttpServletResponse response){
Cookie cookie = new Cookie("cookieName", "root");
response.addCookie(cookie);
System.out.println("response = " + response);
return "response = " + response;
}
}
接收请求头
/**
* 接收请求头:---------------------使用@RequestHeader,形参名等于请求头的名
*/
public class HeaderController {
@RequestMapping("data")
public String data(@RequestHeader String host){
System.out.println("host = " + host);
return "host = " + host;
}
原生对象获取
@Controller
@RequestMapping("api")
@ResponseBody
/**
* 原生对象获取:
* 想要获取什么原生对象直接再形参列表收声明即可
*/
public class ApiController {
//方案二:
@Autowired
private ServletContext context3;
public void data(HttpServletResponse response,
HttpServletRequest request,
HttpSession session){
/**
* 正常使用原生对象即可
* 还有一个常用对象 ServletContext [1.最大配置文件,2.全局最大共享域 3.核心api getRealPath]
* 获取方案一:通过request/session获取
* 获取方案二:直接全局注入
* 声明一个ServletContext全局变量使用@Autowired自动装配
* ServletContext 会自动装入到ioc容器
*/
//方案一:
ServletContext context = request.getServletContext();
ServletContext context1 = session.getServletContext();
}
}