# ceshi **Repository Path**: Answersz/ceshi ## Basic Information - **Project Name**: ceshi - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-06-23 - **Last Updated**: 2025-06-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## SpringMVC #### ssm:mybatis+Spring+SpringMVC MVC三层架构 **1.什么是MVC:** > MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范 > > **Servlet处理:** > > 1. 用户发请求 > 2. Servlet接受请求数据,并调用对应的业务逻辑方法 > 3. 业务处理完毕,返回更新后的数据给servlet > 4. servlet转向JSP,由JSP来渲染页面 > 5. 响应给前端更新后的页面 > > **mvc:** > > Controller层: > > 1. 取得表单数据 > 2. 调用业务逻辑 > 3. 转向指定的页面 > > Model层: > > 1. 业务逻辑 > 2. 保存数据的状态 > > View 视图: > > 1. 显示页面 ### 1 回顾Servlet 1. 直接创建Maven项目,不需要添加其他工程 image-20211204112902709 2. 导入父依赖 ```xml junit junit 4.13.2 test org.springframework spring-webmvc 5.3.12 javax.servlet servlet-api 2.5 javax.servlet jstl 1.2 ``` 3.添加为web项目 ![image-20211204113028384](E:\JavaWorkSpaces\ssmproject\README.assets\image-20211204113028384.png) ![image-20211204113106118](E:\JavaWorkSpaces\ssmproject\README.assets\image-20211204113106118.png) **步骤:** - 创建java类继承HttpServlet - 重写doGet和doPost方法 ```java package com.smile.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.获取前端参数 String method = req.getParameter("method"); if (method.equals("add")){ req.getSession().setAttribute("msg","执行了add方法"); } if (method.equals("delete")){ req.getSession().setAttribute("msg","执行了delete方法"); } //2.调用业务层 //3.视图转发或重定向 req.getRequestDispatcher("/WEB-INF/jsp/text.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } ``` - 在web.xml中配置 ```xml hello com.smile.servlet.HelloServlet hello /hello index.jsp ``` ### 2 中心控制器(DispatcherServlet) ​ Spring的web框架围绕DispatcherServlet设计,DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始,使用Java5或者以上版本用户可以采用基于注解@Controller声明方式。 #### 2.1 SpringMVC的原理如下图所示: ​ 当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。 ![image-20211204124345134](E:\JavaWorkSpaces\ssmproject\README.assets\image-20211204124345134.png) #### 2.2 SpringMVC执行原理 ![image-20211204133851351](E:\JavaWorkSpaces\ssmproject\README.assets\image-20211204133851351.png) 图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。 简要分析执行流程 DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。 我们假设请求的url为 : http://localhost:8080/SpringMVC/hello 如上url拆分成三部分: http://localhost:8080服务器域名 SpringMVC部署在服务器上的web站点 hello表示控制器 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。 > HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。 > > HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。 > > HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。 > > HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。 > > Handler让具体的Controller执行。 > > Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。 > > HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。 > > DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。 > > 视图解析器将解析的逻辑视图名传给DispatcherServlet。 > > DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。 ##### 2.2.1 XML代码:理解上面原理: > web.xml > > ```xml > > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" > version="4.0"> > > > > springmvc > org.springframework.web.servlet.DispatcherServlet > > > contextConfigLocation > classpath:springmvc-servlet.xml > > > 1 > > > > > > springmvc > / > > > ``` > > springmvc-servlet > > ```xml > > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation="http://www.springframework.org/schema/beans > http://www.springframework.org/schema/beans/spring-beans.xsd"> > > > > > > > > > > > > > > > > > ``` > > HelloController > > ```java > import org.springframework.web.servlet.ModelAndView; > import org.springframework.web.servlet.mvc.Controller; > > import javax.servlet.http.HttpServletRequest; > import javax.servlet.http.HttpServletResponse; > import org.springframework.web.servlet.mvc.Controller; > > public class HelloController implements Controller { > public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { > //ModelAndView 模型和视图 > ModelAndView mv = new ModelAndView(); > > //封装对象,放在ModelAndView中。Model > mv.addObject("msg","HelloSpringMVC!"); > //封装要跳转的视图,放在ModelAndView中 > mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp > return mv; > } > } > ``` ##### 2.2.2 注解版SpringMVC[重点] 注意:在视图解析器中我们把所以的视图都放在/WEB-INF/目录下,这样可以保证视图安全,因为这个目录下的文件,客户端不能直接访问 **步骤:** 1. 新建一个web项目 ```xml springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc-servlet.xml 1 springmvc / ``` 2. 导入相关jar包 ```xml 4.0.0 org.example springMVC pom 1.0-SNAPSHOT //此处需注意 spring-01-servlet spring-02-hellomvc spring-02-hellomvc2 spring-03-annocation junit junit 4.13.2 test org.springframework spring-webmvc 5.3.12 javax.servlet servlet-api 2.5 javax.servlet jstl 1.2 src/main/resources **/*.properties **/*.xml false src/main/java **/*.properties **/*.xml false ``` 3. 编写web.xml,注册DispatcherServlet 4. 编写springmvc配置文件 ```xml ``` 5. 创建对应的控制类:controller ```java package com.smile.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/hello") public class HelloController { //真实访问地址:项目名/HelloController/hello @RequestMapping("/h1") public String hello(Model model){ //封装数据:向模型中添加属性msg与值 可以在也页面使用 model.addAttribute("msg", "helloSpringMVC Annocation ok"); //web-inf/jsp/hello.jsp return "hello"; //会被视图解析器处理 } } ``` 6. 完善前端视图和controller之间的对应 7. 测试运行调试 ##### 使用springMVC必须配置的三大件: **处理器映射器、处理器适配器、视图解析器** 在注解中我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解取代即可。 ### 3 RequetMapping @RequestMapping:注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上,用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。 ### 4RestFul风格 ​ Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件更简洁,更有层次感,更易于实现缓存等机制。 ```java package com.smile.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @Controller public class RestFulController { //原来的 : http://localhost:8080/add?a=1&b=3 //RestFul: http://localhost:8080/add/a/b //使用RestFul时,@PathVariable为请求参数 同时请求路径做修改,不同的请求方式Post或Get访问对应的, // @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET) @GetMapping("/add/{a}/{b}") public String test1(@PathVariable int a, @PathVariable int b, Model model){ int res = a+b; model.addAttribute("msg","result is :"+res); return "test1"; } @PostMapping("/add/{a}/{b}") public String test2(@PathVariable int a, @PathVariable int b, Model model){ int res = a+b; model.addAttribute("msg","result2 is :"+res); return "test1"; } } ``` ##### 组合注解: > @GetMapping > > @PostMapping > > @DeleteMapping > > @PutMapping > > @PatchMapping ### 5 SpringMVC 数据处理 ##### 5.1 重定向和转发 ```java //不需要视图解析器情况下: @PostMapping("/m1/t1") public String test3(Model model){ model.addAttribute("msg","result2 is :"+res); //重定向:地址会改变 return "redirect:/test1.jsp"; //转发 :地址不会变 return "test1"; } ``` ##### 5.2 后端数据处理 **1、提交的域名称和处理方法的参数名一致** 提交数据 : http://localhost:8080/hello?name=贾富荣 处理方法 : ```java @RequestMapping("/hello") public String hello(String name){ System.out.println(name); //贾富荣 return "hello"; } ``` **2、提交的域名称和处理方法的参数名不一致** 提交数据 : http://localhost:8080/hello?username=jia 处理方法 : ```java //@RequestParam("username") : username提交的域的名称 . @RequestMapping("/hello") public String hello(@RequestParam("username") String name){ System.out.println(name); //jia return "hello"; } ``` **3、提交的是一个对象** 要求提交的表单域和对象的属性名一致 , 参数使用对象即可 1、实体类 ```java public class User { private int id; private String name; private int age; //构造 //get/set //tostring() } ``` 2、提交数据 : http://localhost:8080/mvc04/user?name=jia&id=1&age=15 3、处理方法 : - ​ 接收前端用户传递的参数,判断参数的名字,假如名字直接在方法上,可直接使用 - 假设传递的参数是一个对象User。匹配User对象中的字段名:如果名字一致则ok,否则为null ```java @RequestMapping("/user") public String user(User user){ System.out.println(user); return "hello"; } ``` 后台输出 : User { id=1, name='jia', age=15 } 说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。 ##### 5.3 数据显示到前端 **第一种 : 通过ModelAndView** ```java public class ControllerTest1 implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { //返回一个模型视图对象 ModelAndView mv = new ModelAndView(); mv.addObject("msg","ControllerTest1"); mv.setViewName("test"); return mv; } } ``` **第二种 : 通过ModelMap** ```java @RequestMapping("/hello") public String hello(@RequestParam("username") String name, ModelMap model){ //封装要显示到视图中的数据 //相当于req.setAttribute("name",name); model.addAttribute("name",name); System.out.println(name); return "hello"; } ``` **第三种 : 通过Model** ```java @RequestMapping("/ct2/hello") public String hello(@RequestParam("username") String name, Model model){ //封装要显示到视图中的数据 //相当于req.setAttribute("name",name); model.addAttribute("msg",name); System.out.println(name); return "test"; } ``` > Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解; > > ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性; > > ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。 ### 6 乱码问题 1. Post请求乱码,Get请求正常 ```java @Controller public class EncodingController { //过滤器解决乱码 @GetMapping("/e/t") //@PostMapping("/e/t") //使用Post请求乱码,get正常 public String test1(String name, Model model){ model.addAttribute("msg", name); return "test1"; } } ``` 2. SpringMVC给我们提供了一个过滤器 , 可以在web.xml中配置 (判断是否已解决?) ```xml encoding org.springframework.web.filter.CharacterEncodingFilter encoding utf-8 encoding /* ``` 3. 修改tomcat配置文件:设置编码 ​ server.xml: ```xml ``` 4.终极 自定义过滤器 ```java package com.smile.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map; /** * 解决get和post请求 全部乱码的过滤器 */ public class GenericEncodingFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //处理response的字符编码 HttpServletResponse myResponse=(HttpServletResponse) response; myResponse.setContentType("text/html;charset=UTF-8"); // 转型为与协议相关对象 HttpServletRequest httpServletRequest = (HttpServletRequest) request; // 对request包装增强 HttpServletRequest myrequest = new MyRequest(httpServletRequest); chain.doFilter(myrequest, response); } public void init(FilterConfig filterConfig) throws ServletException { } } //自定义request对象,HttpServletRequest的包装类 class MyRequest extends HttpServletRequestWrapper { private HttpServletRequest request; //是否编码的标记 private boolean hasEncode; //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰 public MyRequest(HttpServletRequest request) { super(request);// super必须写 this.request = request; } // 对需要增强方法 进行覆盖 @Override public Map getParameterMap() { // 先获得请求方式 String method = request.getMethod(); if (method.equalsIgnoreCase("post")) { // post请求 try { // 处理post乱码 request.setCharacterEncoding("utf-8"); return request.getParameterMap(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } else if (method.equalsIgnoreCase("get")) { // get请求 Map parameterMap = request.getParameterMap(); if (!hasEncode) { // 确保get手动编码逻辑只运行一次 for (String parameterName : parameterMap.keySet()) { String[] values = parameterMap.get(parameterName); if (values != null) { for (int i = 0; i < values.length; i++) { try { // 处理get乱码 values[i] = new String(values[i] .getBytes("ISO-8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } } hasEncode = true; } return parameterMap; } return super.getParameterMap(); } //取一个值 @Override public String getParameter(String name) { Map parameterMap = getParameterMap(); String[] values = parameterMap.get(name); if (values == null) { return null; } return values[0]; // 取回参数的第一个值 } //取所有值 @Override public String[] getParameterValues(String name) { Map parameterMap = getParameterMap(); String[] values = parameterMap.get(name); return values; } } ``` 去web.xml配置 ```xml encoding com.smile.filter.GenericEncodingFilter encoding /* ``` ### 7JSON json的全称为:JavaScript Object Notation,是一种轻量级的数据交互格式。 前端JavaScript自带JSON: ```html ``` ##### 7.1 Jackson ##### 7.2 Fastjson ### 问题: ##### 1. 404错误: ![image-20211204131454429](E:\JavaWorkSpaces\ssmproject\README.assets\image-20211204131454429.png) 查看是否存在lib包 ![image-20211204131405731](E:\JavaWorkSpaces\ssmproject\README.assets\image-20211204131405731.png) 解决方案: ![image-20211204131723254](E:\JavaWorkSpaces\ssmproject\README.assets\image-20211204131723254.png) ##### 2.idea中lib导入失败 在pom.xml中添加如下代码: ```xml src/main/resources **/*.properties **/*.xml false src/main/java **/*.properties **/*.xml //注意 false ```