- 1 Spring MVC介绍
- 1.1 服务端代码分为三层
- 1.2 表现层的代码分为三层
- 1.3 处理请求的过程
- 2 Thymeleaf介绍
- 3 示例
- 3.1 测试接收请求数据
- 3.1.1 接收从URL传进来的参数
- 3.1.2 接收从POST请求传入的数据
- 3.2 测试返回响应数据
- 3.2.1 响应HTML
- 3.2.2 响应JSON数据
对于服务端的程序来说,我们首要解决的是如何处理浏览器端的请求,在这方面,Spring MVC是最流行的技术。
1.1 服务端代码分为三层服务端开发的代码是有层次的,分层的目的是解耦、易于维护。
服务端的代码分为三层,分别是:表现层/业务层/数据层。
浏览器访问服务器,首先访问表现层,期待表现层给它一些数据,表现层会调用业务层处理业务,业务层在处理业务过程中会调用数据访问层来访问数据库。表现层(Controller)得到业务层返回的数据封装在Model里传给视图层View,View利用数据生成html返回给浏览器
Spring MVC是一种设计模式,理念是将复杂的代码分为三个层次
C - Controller:控制器。接受用户请求,调用 Model 处理,然后选择合适的View给客户。
M - Model:模型。业务处理模型,接受Controller的调遣,处理业务,处理数据。
V - View:视图。渲染
Spring官方手册:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-servlet
HandlerMapping:敲一个路径,利用HandlerMapping来匹配到对应的Controller,我们所写的RequestMapping注解就是由HandlerMapping来管理的
1.3 处理请求的过程
浏览器传入的请求由前端控制器处理(就是DispatcherServlet)
DispatcherServlet根据注解RequestMapping找到对应的Controller
Controller把处理后得到的数据封装在Model里返回给DispatcherServlet
DispatcherServlet把Model传给View
View渲染之后返回DispatcherServlet
DispatcherServlet返回给浏览器
作用:生成动态的HTML
模板文件包含了HTML静态页面和一些表达式,这些表达式可以被model中的数据替换,model传进去不同的数据,HTML就可以动态变化
官网:https://www.thymeleaf.org/
文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#what-kind-of-templates-can-thymeleaf-process
语法文档上都有,常用语法:标准表达式(对应文档小标题4)、判断与循环(6、7)、模板布局(8)
是个小示例就不写数据访问层和业务层了
(其中数据访问层已在MyBatis入门里演示过)
视图层包含在controller文件夹里的Controller和resource文件下的templates文件夹下的动态模板
Controller:
1.写注释@Controller
2.(这步可省略)写映射地址
3.里面写方法,方法前面写映射地址
@RequestMapping("/request")
public void testRequest(HttpServletRequest request,HttpServletResponse response){
System.out.println(request.getMethod());//请求方法
System.out.println(request.getServletPath());//请求路径
Enumeration enumeration = request.getHeaderNames();
while(enumeration.hasMoreElements()){
String name = enumeration.nextElement();
String value = request.getHeader(name);
System.out.println(name+":"+value);
}
response.setContentType("text/html;charset=utf-8");
try(
PrintWriter writer = response.getWriter();
){
writer.write("i get your request");
}catch (IOException e){
e.printStackTrace();
}
}
1.用@RequestParam
// /students?current=1&limit=20
@RequestMapping(path = "/students" , method = RequestMethod.GET)
@ResponseBody//返回一个简单的字符串
//1.要怎么获取请求的参数呢?方法的参数名称与请求的参数名称一致就行了
//DispatcherServlet检测到方法有参数之后,就会把请求中与之匹配的参数传进来
//如果请求没有传来参数怎么办呢?需要在方法参数前面加上注解。注解中第二个参数:可以不传;第三个参数:不传的话默认值
public String getStudents(
@RequestParam(name = "current",required = false,defaultValue = "1") int current ,
@RequestParam(name = "limit",required = false,defaultValue = "10") int limit){
System.out.println(current);
System.out.println(limit);
return "some students";
}
2.用@PathVariable
//2 根据学生id查询一个学生的信息:/student/123 直接把参数编排到路径中
@RequestMapping(path = "/student/{id}",method = RequestMethod.GET)
@ResponseBody
public String getStudent(@PathVariable("id") int id){
System.out.println(id);
return "a student";
}
3.1.2 接收从POST请求传入的数据
增加学生
访问一下试试,重新编译,访问static里的静态页面,路径里static不用打
属性名写得和网页一致就行了,DispatcherServlet匹配到该方法之后会自动将传入数据与方法参数做匹配
@RequestMapping(path = "/student",method = RequestMethod.POST)
@ResponseBody
public String saveStudent(String name,int age){
System.out.println("姓名:"+name+",年龄:"+age);
return "success!";
}
3.2 测试返回响应数据
@Controller
@RequestMapping("/demo")
public class DemoController {
@RequestMapping("/response")
//测试一下返回响应数据
public void testResponse(HttpServletResponse response) {
//浏览器返回的类型是HTML
response.setContentType("text/html;charset=utf-8");
try(
PrintWriter writer = response.getWriter();
){
writer.write("hello,this is a response demo!");
}catch (IOException e){
e.printStackTrace();
}
}
}
调试一下,writer里的数据在response里的hb里存着的
这应该算是计网里的内容
Connection不了解
Content-Length: 我的响应一共39个字符
Content-Type:响应类型,我在程序里设置过(不设置的话,响应头里没这句,但是页面还是可以解析成HTML语句)
Data:时间
Keep-Alive:不了解
HttpServletResponse是谁创建的?老师说的是把HttpServletResponse写在方法参数里,SpringMVC里的DispatcherServlet在调用该方法时会自动把HttpServletResponse对象传给方法
3.2.1 响应HTML在templates目录下新建一个test文件夹,里面新建view2.html
Teacher
//返回html文件
@RequestMapping(path = "/teacher" ,method = RequestMethod.GET)
public ModelAndView getTeacher(){
ModelAndView mav = new ModelAndView();
mav.addObject("name", "李老师");
mav.addObject("age", 30);
mav.setViewName("/test/view2");//返回templates目录下html的文件路径
return mav;
}
现在显示的这个页面就是view2.html被模板引擎动态渲染之后的页面
还有一种更简单一点的调用方式
返回的类型是String,就是返回的动态模板的路径
@RequestMapping(path = "/school",method = RequestMethod.GET)
public String getSchool(Model model){
model.addAttribute("name","电子科技大学");
model.addAttribute("age",65);
return "/test/view2";
}
3.2.2 响应JSON数据
在异步请求中要响应JSON数据
举例:在某网站注册时,输入昵称,网站会查询服务器该昵称是否被占用,然后以异步请求的方式返回到网页
@ResponseBody 不加该注解默认返回html
@RequestMapping(path = "/emp",method = RequestMethod.GET)
@ResponseBody
public Map getEmp(){
Map emp = new HashMap<>();
emp.put("name", "张三");
emp.put("age", 23);
emp.put("salary", 8000);
return emp;
}
DispatcherServlet看到该方法加了@ResponseBody,并且返回类型为Map,就会自动把Map转成JSON字符串
还可以往外面再包一层:多组相似数据
基本上所有数据都可以通过这种方式转成JSON返回网页
@RequestMapping(path = "/emps",method = RequestMethod.GET)
@ResponseBody
public List



