一、MVC设计模式:
作用:用来进行分层的结构,这样代码分离结构清晰,各层代码,各司其职,易于开发大型项目。
MVC(Model模型、View视图、Control控制层),将软件进行分层达到松耦合的效果。
在MVC设计思想中要求一个符合MVC设计思想的软件应该保证上面这三部分相互独立,互不干扰,每一个部分只负责自己擅长的部分。如果某一个模块发生变化,应该尽量做到不影响其他两个模块。提高代码的可读性,实现程序间的松耦合、提高代码复用性。
SpringMVC就是基于MVC设计模式来实现的。
我们的POJO/domain就是Model层,我们的JSP就是视图层,我们的Controller就是控制层。
现在主流基于SSM三大框架开发都是在MVC上继续演化,又分为持久层DAO,业务层Servie,控制层Controller。持久层用来和数据库读写ORM,业务层用来处理复杂的业务逻辑,控制层用来处理MVC的控制。
二、SpringMVC工作原理:
Springmvc的五大组件:DispatcherServlet(前端控制器)、HandlerMapping(映射处理器)、controller(控制器)、ModelAndView、ViewReslover(视图解释器)
当客户端发起请求,首先经过DispatcherServlet(前端控制器),DispatcherServlet将请求分发给HandlerMapping(映射处理器),通过HandlerMapping 根据指定的controller名字,找到对应的Controller组件处理请求,(->service->mapper )那么将得到的数据绑定在ModelAndView组件中,最后通过ViewReslover(视图解析器) 解析数据与视图 渲染到页面。
说明:
当服务器启动的时候,首先会去加载web.xml文件(可以理解问web应用程序的入口)
凡是放在WEN-INF文件夹下面的资源都是受保护的,不能通过浏览器直接访问,可以通过转发或者重定向进行访问。
三、服务器与控制层的传参方式:
1、路径传参:
//客户端 向 服务端传参
/*
在浏览器地址栏使用路劲传参
localhost:8060/t1?name='lisi'&age=10
name和age要一致
*/
@RequestMapping("/t1")
public void test1(String name,Integer age){
/*String str = "123";
Integer strInt = Integer.parseInt(str);强制类型转换*/
System.out.println(name);
System.out.println(age);
}
2、使用HttpServletRequest 请求对象 获取参数
/*
* 使用HttpServletRequest 请求对象 获取参数
* 使用HttpServletRequest和HttpServletResponse时需要
* */
@RequestMapping("/t2")
public void test2(HttpServletRequest request){
String name = request.getParameter("name");
String age = request.getParameter("age");
System.out.println(name);
System.out.println(age);
}
3、使用JSP页面的表单传参:
//表单传参 使用表单的name属性值 作为参数传到服务端
//服务端的参数名和表单的name 属性值一致即可
//浏览器传入到服务器的参数都是String类型的
//但是对于数字类型的字符串,在服务端可以使用Integer来接收。
//因为SpringMVC框架自动完成类型转换
/*
* get请求和post请求的区别:
* get请求会将表单的数据暴露在浏览器的地址栏,对于重要的数据是不安全的
* post请求是将表单数据封装在请求行里面,数据比较安全
* get请求提交的数据量比post的要小
* 表单请求默认是get请求
* */
@RequestMapping("/doLogin")
public void doLogin(HttpServletRequest request){
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
System.out.println(username);
System.out.println(pwd);
}
JSP代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>注册</h1>
<form action="/doReg" method="post">
<p>
用户名:<input type="text" name="username" placeholder="请输入用户名">
</p>
<p>
密码:<input type="password" name="pwd" placeholder="请输入密码">
</p>
<p>
联系方式:<input type="text" name="tel" placeholder="请输入联系方式">
</p>
<p>
<input type="submit">
</p>
</form>
</body>
</html>
4、表单封装实体类对象向服务端传参:
/*
* 表单封装实体对象 向服务端传参
* 当表单的name属性值与实体类的属性一致的时候,
* SpringMVC会将表单数据自动封装到实体类中,
* 那么,可以在服务端直接传入对象即可
* */
//当在浏览器输入localhost:8060/reg-->reg.jsp
/*
* 转发和重定向:解决页面跳转的问题
* 转发:request.getRequestDispatcher("去哪个页面").forward(request,response);
* 重定向:response.sendRedirect("去哪个页面或路径");
* 区别:
* 转发只能在项目内部进行,而重定向可以跳转到项目外的任意页面
* 转发是一次请求,重定向是两个请求
* 转发地址栏的请求路径不会变,而重定向的地址栏会发生改变
* */
@RequestMapping("/reg")
public String toReg(){
return "reg";
//return "redirect:reg";默认是转发,加了redirect就是重定向
}
@RequestMapping("/doReg")
public void doReg(User user){
System.out.println(user.toString());
}
5、利用Model获取浏览器参数:
//跳转到t1.jsp
@RequestMapping("/toT1")
public String toT1page(){
return "t1";
}
//接收toOrderDate请求
@RequestMapping("/toOrderDate")
public String toOrderDate(String name, Model model){
//目的:将name值绑定到t2.jsp页面
//使用model对象绑定数据
model.addAttribute("username",name);
return "t2";
}
t1.jsp代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="/toOrderDate?name='旺财'"> 订单中心</a>
</body>
</html>
t2.jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
订单用户名:${username}
<br>
工资是:${salry}
<br>
名字是:${name}
<br>
年龄是:${age}
<br>
地址是:${address}
<br>
电话是:${tel}
<br>
email是:${email}
</body>
</html>
6、使用HttpServletRequest 对象绑定数据:
//使用HttpServletRequest 对象绑定数据
@RequestMapping("/t3")
public String t3(HttpServletRequest request){
request.setAttribute("salry",2000);
request.setAttribute("name","旺财");
return "t2";
}
7、使用ModelAndView对象绑定数据
//使用ModelAndView对象绑定数据
@RequestMapping("/t4")
public ModelAndView t4(ModelAndView modelAndView){
//ModelAndView绑定数据
modelAndView.addObject("age",100);
//ModeAndView绑定视图
modelAndView.setViewName("t2");
return modelAndView;
}
8、使用HttpSession对象绑定数据
//使用HttpSession对象绑定数据
@RequestMapping("/t5")
public String t5(HttpSession session){
//使用session绑定数据
/*
* session和cookie区别:
* 记录用户的状态(数据)
* session将数据绑定在数据端,由session绑定的数据可以实现数据共享
* cookie将数据保存在客户端(浏览器中,不安全)
* */
session.setAttribute("address","湛江市");
return "t2";
}
9、使用ServletContext绑定数据:
//ServletContext绑定数据
@RequestMapping("/t6")
public String t6(HttpServletRequest request){
//使用请求对象request获取ServletContext对象
ServletContext context = request.getServletContext();
//使用ServletContext绑定数据
context.setAttribute("tel","123597648");
return "t2";
}
10、使用HttpServletResponse响应对象:
//使用HttpServletResponse响应对象
@RequestMapping("/t7")
public void t7(HttpServletResponse response) throws IOException {
//告诉浏览器输出内容以及编码格式
response.setContentType("text/html;charset=utf-8");
//通过HttpServletResponse
PrintWriter writer = response.getWriter();
//使用PrintWriter写出内容
writer.println("服务器正忙,请稍后重试!");
writer.close();
}
11、将方法返回的数据转成JSON字符串:
@RequestMapping("/t8")
@ResponseBody//将方法返回的数据转成JSON字符串
public User t8(){
//将数据封装到User对象中
User user = new User();
user.setUsername("李四");
user.setPwd("123456");
user.setTel("18219478028");
/*最终返回的JSON串格式
* "{"username":"李四","pwd"="123456","tel"="18219478028"}"
* */
return user;
}
12、将List集合转成JSON字符串返回给浏览器:
//将List集合转成JSON字符串返回给浏览器
@RequestMapping("/t10")
@ResponseBody
public List<User> t10(){
List<User> list = new ArrayList<>();
//向集合添加元素
User user = new User();
user.setUsername("旺财");
user.setPwd("125312");
user.setTel("415664855");
list.add(user);
User user1 = new User();
user1.setUsername("小花");
user1.setPwd("125112");
user1.setTel("4156611222");
list.add(user1);
return list;
}
13、将Map集合转成JSON字符串:
//将Map集合转成JSON字符串
@RequestMapping("/t11")
@ResponseBody
public Map<String,Object> t11(){
Map<String,Object> map = new HashMap<>();
//向map集合添加数据
map.put("state",200);
map.put("msg","手机验证码已发送");
return map;
}
补充:json(前后端交互时常常使用的一种数据交换格式)
四、注解
(1)什么是注解
- @ 是java注解,即annotation。
- 可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件。
3.Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起 到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用
(2)什么时候用?
我们一般用不到自定义注解,框架为我们提供了很多注解,只要在代码里写明你需要的注解就可以了。只有在自己动手写类似于Hibernate框架的时候,会用到自定义注解。这也是为什么我们一般用不到java反射,因为只有在使用自定义注解的时候,才会用到java反射,而我们平时连自定义注解都用不到。
(3)XML配置方式和注解方式差异
- Controller无需在xml中声明,加个@Controller注解即可,这样再多的Controller也不怕了。只需xml中配置一次注解驱动<mvc:annotation-driven />
- 原来要在xml配置bean来指明映射关系,现在只加注解@RequestMapping无需xml配置
- 无需返回ModelAndView对象,直接返回逻辑名即可
- 参数自动封装,自动类型转换
(4)常用的注解:
@Controller 标识是一个Controller,Spring包扫描创建实例
@RequestMapping 请求后的映射路径
@PathVariable 标识接收单个参数
@RespringBody 返回对象利用jackson工具类转换为json字符串
@RequestParam 参数名和请求参数名称不同时使用,可以设置默认值