目录

  • 1 常识
    • 1.1 回顾jsp/servlet
  • 2 springmvc
    • 2.1 QuickStart(原理讲解,实际中不使用该步骤)
    • 2.2 QuickStart
    • 2.3 总结
  • 3 controller详解
    • 3.1 实现接口
    • 3.2 注解方式
    • 3.3 RESTful风格
    • 3.4 结果跳转方式
    • 3.5 请求参数
    • 3.6 返回结果
  • 4 乱码问题
    • 4.1 servlet过滤器
    • 4.2 spring过滤器
    • 4.3 其他方法
  • 5 JSON(@RestController)
  • 6 SSM整合
  • 7 Ajax
  • 8 拦截器
    • 8.1 拦截器Demo:登录拦截
  • 9 文件上传

1 常识

ssm:spring+springmvc+mybatis MVC三层架构

MVC:将业务逻辑、显示、数据分离
模型model(dao,service,负责底层数据库的连接和增删改查操作)
视图view(jsp/html,展示数据)
控制器controller(servlet,获取请求和返回响应)

POJO:实体类,包含这个实体的所有属性
VO:视图层对象,用于转化请求中的参数到对象中去,仅仅包含view层所需属性,相当于POJO的精简版
DTO:数据传输对象,用于存储service层所需的参数

接下来的学习方向:springmvc-vue-springboot-springcloud-linux

重点:springmvc的执行流程!!!

springmvc优点:
1 方便利用spring其他功能
2 自动绑定输入,正确转换数据类型
3 内置校验器
4 多种视图技术
5 使用xml配置文件

1.1 回顾jsp/servlet

转发和重定向

转发的特点:
1.地址栏不发生变化,显示的是上一个页面的地址
2.请求次数:只有1次请求
3.根目录:http://localhost:8080/项目地址/,包含了项目的访问地址
4.请求域中数据不会丢失
转发使用:request.getRequestDispatcher("/地址").forward(request, response);

重定向的特点:
地址栏:显示新的地址
请求次数:2次
根目录:http://localhost:8080/ 没有项目的名字
请求域中的数据会丢失,因为是2次请求

结论:如果要保留请求域中的数据,使用转发,否则使用重定向。无论转发或重定向后续的代码都会执行。

  1. 新建空白Maven工程,并添加框架支持:JaveWeb
  2. 导入相关依赖
      <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency>
    
  3. 创建一个servlet类
    public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取前端参数String method = req.getParameter("method");if("add".equals(method)){req.getSession().setAttribute("msg","do add");}if("delete".equals(method)){req.getSession().setAttribute("msg","do delete");}// 调用业务// 转发或重定向req.getRequestDispatcher("/WEB-INF/jsp/doMethod.jsp").forward(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
    }
    
  4. 创建对应页面
    注意:如果需要保证用户不可见,需要放在WEB-INF下面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    ${msg}
    </body>
    </html>
    
  5. 配置web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"><display-name>Welcome to Tomcat</display-name><description>Welcome to Tomcat</description><servlet><servlet-name>hello</servlet-name><servlet-class>com.xiaopi3.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping><session-config><session-timeout>15</session-timeout></session-config>
    </web-app>
    

2 springmvc

简单易学,高效,基于请求和响应,约定优于配置

功能强大,支持RESTful风格,数据验证,格式化,本地化,主题

围绕DispatcherServlet设计,可以将请求发送给不同的处理器(spring2.5后使用java5可以使用注解controller声明方式)

以请求为驱动

2.1 QuickStart(原理讲解,实际中不使用该步骤)

可能遇到的问题:
1.控制台输出显示缺少jar包(典型的,缺少请求分发器)
2 查看idea的项目结构中的artifact中的WEB-INF下是否有lib库,没有则手动添加,并导入所有jar包
3 重启tomcat

执行步骤:

  1. 浏览器发送请求给DispatcherServlet
  2. DispatcherServlet接收请求,给HandlerMapping去解析请求,寻找对应的HandlerExecution
  3. 找到HandlerExecution后,返回给DispatcherServlet,DispatcherServlet再去调用HandlerAdapter去执行该HandlerExecution,HandlerExecution中包装的就是Controller层的控制器类,执行过程中控制层会调用业务层,最终返回一个ModelAndView给HandlerAdapter
  4. HandlerAdapter拿到ModelAndView给DispatcherServlet,DispatcherServlet调用视图解析器ViewResolver,解析出数据和目标视图页面
  5. 跳转到终页面并插入数据

步骤:
1 编写跳转视图myhello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><body>${msg}</body>
</html>

2 配置web.xml,装在请求分发器,地址映射,初始化配置(加载springmvc的配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0">
<!--核心配置:请求分发器--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--    绑定spring配置文件--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param>
<!--    启动级别:1,表示tomcat服务后就启动--><load-on-startup>1</load-on-startup></servlet>
<!--请求映射:注意!这里/和/*有区别!前者只匹配请求,后者匹配请求+jsp页面--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

注意:请求映射里的/和/*区别很大!
/:只转发给请求分发器动作请求,不转发文件请求
/*:转发所有请求
由于请求分发器会自动拼接动作请求,并且最后加上jsp后缀,所以使用/*会导致无限循环!

如果是过滤器,url-pattern必须为/*才行
如果想看过滤器过滤了什么请求:String url = ((HttpServletRequest) request).getRequestURI();

3 配置springmvc-servlet.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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--    装配处理器映射器,bean名称映射器会去在beans中寻找匹配的bean名字--><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--    装配处理器适配器--><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--    视图解析器:即模板引擎,可替换的有Thymeleaf,Freemarker--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--        前缀--><property name="prefix" value="/WEB-INF/jsp/"/>
<!--        后缀--><property name="suffix" value=".jsp"/></bean><bean id="/hello" class="com.xiaopi3.controller.HelloController"/></beans>

注意:如果采用的是实现接口的方式实现控制器,则处理器映射器处理器控制器不用显示写,默认有。
4 配置controller类

public class HelloController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView mv = new ModelAndView();// 业务代码String result = "hahahah";mv.addObject("msg",result);// 视图跳转mv.setViewName("myhello");// 会被视图解析器拼接成/WEB-INF/myhello.jspreturn mv;}
}

5 启动tomcat部署项目,请求/hello地址发现显示正常

2.2 QuickStart

注意:可以添加一下打包过滤文件:

<build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource></resources>
</build>

https://www.cnblogs.com/dflmg/p/6393416.html
步骤:

  1. 配置web.xml(基本不用变,每次写都直接copy即可),同上节一样
  2. 配置springmvc-servlet.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:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd
"><!--    包扫描可以实现启用注解(annotation-config),并且可以实现自动装配bean--><context:component-scan base-package="com.xiaopi3.controller"/>
<!--    过滤静态资源请求,交由web容器默认servlet去处理--><mvc:default-servlet-handler/>
<!--    mvc注解驱动:注入处理器映射器和处理器适配器,注解方式,可以不显示写--><mvc:annotation-driven/>
<!--    配置视图解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean>
</beans>
  1. 新建控制器类:com.xiaopi3.controller下,该类包含控制器和映射器注解!!
@Controller // 注意:该控制器注解会被视图解析器解析,如果是@RestController则直接返回到前端,不解析!!
@RequestMapping("/to") // 一级地址
public class HelloController {// 二级地址@RequestMapping("/hello")public String hello(Model model){// 封装数据model.addAttribute("msg","my first annotation springmvc!");return "hello"; // 会被视图解析器处理,该字符串会作为视图名称}
}
  1. 新建jsp页面(对应于return字符串中的,被视图解析器组合后为:/WEB-INF/jsp/hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
${msg}
</body>
</html>

注意:如果碰到包找不到的报错,看一下上一节开头的提示
注意:@Controller@RestController的区别:前者注解会被视图解析器解析,后者则直接返回到前端,不解析!!

2.3 总结

springmvc中必备三大项:处理器映射器,处理器适配器,视图解析器,其中,前两者被:annotation-driver干掉了,只需配置最后一个,并开启注解驱动!

3 controller详解

控制器可以通过两种方式实现:通过实现接口Controller返回ModelAndView(不推荐),通过注解!
负责解析用户请求,并处理成模型

3.1 实现接口

配置springmvc-servlet.xml,该方式无需显示装配处理器映射器和处理器控制器
配置控制器映射类+视图解析器即可!

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/>
</bean>
<bean id="/hello" class="com.xiaopi3.controller.HelloController"/>

编写控制器

public class HelloController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView mv = new ModelAndView();String result = "hahahah";mv.addObject("msg",result);mv.setViewName("myhello");// 会被视图解析器拼接成/WEB-INF/myhello.jspreturn mv;}
}

总结:该方法以及不推荐使用,因为一个类只能映射一个请求,当请求过多,需要写很多类

3.2 注解方式

配置springmvc-servlet.xml (注意,最好不要加中文注释!有可能报编码异常!!)
配置扫描包+视图解析器即可

<context:component-scan base-package="com.xiaopi3.controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/>
</bean>

新建控制器类:com.xiaopi3.controller下,该类包含控制器和映射器注解!!
加上@Controller@RequestMapping即可

@Controller // 注意:该控制器注解会被视图解析器解析,如果是@RestController则直接返回到前端,不解析!!
@RequestMapping("/to") // 一级地址
public class HelloController {// 二级地址@RequestMapping("/hello")public String hello(Model model){// 封装数据model.addAttribute("msg","my first annotation springmvc!");return "hello"; // 会被视图解析器处理,该字符串会作为视图名称}
}

3.3 RESTful风格

一种资源定位和操作的风格,简洁、高效、安全
所有参数传递都采用/进行分割,类似于下面这种:

采用不同的请求方式来区分

对应的Controller类如下:

原始风格:

@RequestMapping("/add")
public String add(int a,int b,Model model){int res = a+b;model.addAttribute("msg","结果为:"+res);return "hello";
}

请求地址:/add?a=1&b=2

RESTful风格:

@RequestMapping("/add/{a}/{b}")
public String add2(@PathVariable int a,@PathVariable int b,Model model){int res = a+b;model.addAttribute("msg","结果为:"+res);return "hello";
}

请求地址:/add/4/6
改动两个地方:1. 地址栏通过{x}获取变量x的值;2. 参数列表通过@PathVariable绑定地址变量即可

同时可以指定请求方式:@RequestMapping(path="/add/{a}/{b}",method=RequestMethod.GET)
同时上面这种请求又可以简化:@GetMapping("/add/{a}/{b}"),POST|DELETE|PUT|PATCH都有这种简化

3.4 结果跳转方式

1 使用ModelAndView对象,可以设置view名称,跳转到指定页面,经过视图解析器
2 使用servlet api:request重定向和resp转发,方法内依旧能获取req和res(不推荐),不经过视图解析器
3 使用springmvc转发和重定向,不经过视图解析器,底层依旧是servlet api,(可以去掉视图解析器配置)需要写全jsp文件路径名称!

// servlet api 重定向
@RequestMapping("/add")
public String add2(HttpServletRequest req, HttpServletResponse resp){req.getRequestDispatcher("WEB-INF/jsp/test.jsp").forward(req,resp);
}
// servlet api 转发
@RequestMapping("/add")
public String add2(HttpServletRequest req, HttpServletResponse resp){resp.sendRedirect("/index.jsp");
}
// springmvc 重定向
@RequestMapping("/add1")
public String add2(){return "redirect:/index.jsp";
}
// springmvc 转发
@RequestMapping("/add2")
public String add2(){return "/index.jsp";
}
// springmvc 转发
@RequestMapping("/add3")
public String add2(){return "forward:/index.jsp";
}

注意:重定向无法访问WEB-INF下的文件
注意:重定向无法携带原请求的参数,但是可以在指定重定向到哪个url前,在其中添加新参数,新参数会显示在重定向的url后面
注意:转发会携带原参数,但无法携带新数据(实测Spring的Model无法携带)

请求转发地址栏不会发生改变、只发送一次请求、能携带原有的参数,但只可以在同一个服务器中进行转发。

传统的重定向请求地址会改变(两次请求)、不能传递参数,但是利用SpringMVC的重定向可以携带和传递参数。重定向相比于请求转发可以跨服,但是不能直接重定向访问WEB-INF下的资源(可重定向后再进行一次请求转发)。

3.5 请求参数

url中参数名和controller的方法形参一致即可获取请求参数!

// 请求url为:/hello?name=pp&age=2&id=435
@RequestMapping("/hello")
public String a(String name,int age,String id){}

如果参数名称不一致,可以通过@RequestParam("xxx")显式映射url的参数

// 请求url为:/hello?username=pp&age=2&id=435
@RequestMapping("/hello")
public String a(@RequestParam("username")String name,int age,String id){}

可以将请求参数封装称一个实体,只要url请求参数能和实体中的属性名对应即可!没对应的为null

// 请求url为:/hello?name=pp&age=2&id=435
// User类中有name age id属性
@RequestMapping("/hello")
public String a(User user){}

3.6 返回结果

返回结果到前端有三种方式:
Model:只有几种方法用来存储数据(主要)
ModelMap:继承LinkedMap,还有自身的一些方法
ModelAndView:存储数据,可以设置跳转视图

4 乱码问题

实践中往往通过POST方式从网页上传递过来的数据有中文乱码问题,而GET方式没有这个问题,解决方法有两种,servlet过滤器,或者使用spring写好的过滤器

4.1 servlet过滤器

解决方式:

  1. 使用servlet过滤器进行过滤请求
    EncodingFilter.java
public class EncodingFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");chain.doFilter(request,response);}
}
  1. 注册该过滤器
    web.xml
<filter><filter-name>encodingfilter</filter-name><filter-class>com.xiaopi3.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping><filter-name>encodingfilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

注意:此时url为/*即拦截所有的请求,无论是路径还是文件,因为在返回视图时是一个jsp页面,同样需要捕获到该请求页面并转码,而/过滤该请求,只捕获动作,返回时的请求就不会被处理了,我们需要保证请求和响应的编码一致才行

4.2 spring过滤器

<filter><filter-name>springencoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping><filter-name>springencoding</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

spring提供一个编码的过滤器,可以解决乱码问题,可能某些情况下对GET支持不好

4.3 其他方法

  1. 修改tomcat配置文件,设置编码格式:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

5 JSON(@RestController)

html中的script不能自闭合,必须成对出现

轻量级的数据传输格式,使用字符串表示,常用的包有:Jackson、fastjson、gson等

可以将对象转换成字符串,可以从字符串中恢复对象

注意:一般而言,Controller里返回的字符串会通过请求分发器去找视图解析器解析,但是如果想直接返回该字符串给前端的化,必须添加注解:@ResponseBody

注意:如果json中出现乱码,可以配置RequestMapping中的属性:

@RequestMapping(value="j",produces="application/json;charset=utf-8")
@ResponseBody
public String fun1(){}

由于在注解中配置方式,需要每个注解都配置,比较烦,可以在springmvc-servlet.xml中进行配置:

<mvc:annotation-driven><mvc:message-converters><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/><bean class="org.springframework.http.converter.FormHttpMessageConverter"/><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg name="defaultCharset" value="UTF-8"/></bean></mvc:message-converters>
</mvc:annotation-driven>

需要导入jackson包:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.5</version>
</dependency>

再次返回json字符串则显示正常:

@RestController
public class JsonController {@RequestMapping("/j1")public String fun1(){JSONObject json =new JSONObject();json.put("name","小皮3");json.put("age",19);return json.toString();}
}

6 SSM整合

环境:IDEA、MySQL5.7、Tomcat9、Maven3.6

  1. 导入依赖
    pom.xml
<dependencies><!-- https://mvnrepository.com/artifact/junit/junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.1</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.2</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.0</version></dependency><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.5</version></dependency><!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version><scope>provided</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency>
</dependencies><build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource></resources>
</build>
  1. 配置三个配置文件:spring核心配置文件,数据库properties,mybatis配置文件
    db.properties
# 注意,一定要写jdbc.driver而不是driver,要不然有可能会报错!!
jdbc.driver=com.mysql.jdbc.Driver
# 如果是mysql8+,需要添加时区:&serverTimezone=Asia/Shanghai
jdbc.url=jdbc:mysql://localhost:3306/ooo?useSSL=false&useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456

mybatis-config.xml,其他交给spring去管理了

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="com.xiaopi3.pojo"/></typeAliases></configuration>

applicationContext.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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd
"><import resource="classpath:spring-dao.xml"/><import resource="classpath:spring-service.xml"/><import resource="classpath:spring-mvc.xml"/></beans>

第一个:spring-dao配置
配置一下spring和数据库相关的配置
连接池:

  • dbcp:半自动化操作,不能自动连接
  • c3p0:自动化操作(自动加载配置文件,自动设置到对象中)
  • druid
  • hikari

spring-dao.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd
"><context:property-placeholder location="classpath:db.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><property name="maxPoolSize" value="30"/><property name="minPoolSize" value="10"/><property name="autoCommitOnClose" value="false"/><property name="checkoutTimeout" value="10000"/><property name="acquireRetryAttempts" value="2"/></bean><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="configLocation" value="classpath:mybatis-config.xml"/></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/><property name="basePackage" value="com.xiaopi3.dao"/></bean></beans>

配置文件分为几部分:
1 外部properties文件读取
2 c3p0连接池配置
3 sqlSessionFactory注入
4 使用Mapper扫描器对包进行扫描,并注入sqlSessionFactory,该类属于mybatis与spring整合的包

spring-service.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:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd
"><context:component-scan base-package="com.xiaopi3.service"/><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean></beans>

该配置文件分为两部分:
1 包扫描
2 配置spring事务管理器

spring-mvc.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"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd
"><mvc:annotation-driven/><mvc:default-servlet-handler/><context:component-scan base-package="com.xiaopi3.controller"/><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean>
</beans>

该配置文件分为4个部分:
1 注解驱动,mvc注入映射器和适配器
2 静态资源过滤
3 包扫描
4 视图解析器

  1. 配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><session-config><session-timeout>15</session-timeout></session-config>
</web-app>

该配置文件主要做了两件事:
1 配置请求分发器,并注入spring总配置文件(因为时web项目,需要在这里读取总配置文件),设置spring即刻启动
2 配置启用spring编码过滤器

至此配置工作结束,开始业务工作!

对于POJO类可以采用lombok注释

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private int id;private String name;private int age;private int salary;
}

对于dao下的接口采用mybatis的方式:

public interface UserMapper {int addUser(User user);int deleteUserById(int id);int updateUser(User user);User findUser(int id);List<User> findAllUser();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopi3.dao.UserMapper"><insert id="addUser" parameterType="user">insert into `user` values(null,#{name},#{age},#{salary})</insert><delete id="deleteUserById">delete from `user` where id=#{id}</delete><update id="updateUser" parameterType="user">update `user` set name=#{name},age=#{age},salary=#{salary} where id=#{id}</update><select id="findUser" resultType="user">select * from `user` where id=#{id}</select><select id="findAllUser" resultType="user">select * from `user`</select></mapper>

对于控制层controller采用注解方式:

@Controller
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/findAll")public String findAllUser(Model model){List<User> allUser = userService.findAllUser();model.addAttribute("users", JSON.toJSONString(allUser));return "users";}@RequestMapping("/find")public String find(int id,Model model){User user = userService.findUser(id);ArrayList<User> users = new ArrayList<>();users.add(user);model.addAttribute("users", JSON.toJSONString(users));return "users";}
}
  1. 启动tomcat,注意在tomcat的lib下导入需要的jar包,访问请求地址:/user/findAll,完毕

7 Ajax

掌握异步请求方式

<script>
function getValue(){$.post({url:"地址",data:{数据},success:function(data,status,xhr){}})
}
</script>

注意:回调函数中:data为返回值,status为:(“success”、“notmodified”、“error”、“timeout”、“parsererror”)中的一种,xhr为XMLHttpRequest对象
注意:post中可以不传递{}对象,直接传参:$.post(url,bodyData,function(responseData){})

动过标签获取input组件的value值:txt=$("input").val();
通过id获取某个组件:$("#id")
ajax入口函数:$(function(){入口}),写在入口中的表达式会依次执行
ajax设置组件css:$("#id").css("color":"green")

使用Ajax动态获取数据时建议后台使用@RestController来传递数据

@RestController
public class TestRestController {@RequestMapping("/doRest")public List<Map<String,Integer>> doRest(int num){List<Map<String, Integer>> maps = new ArrayList<>();for (int i = 0; i < num; i++) {Map<String, Integer> map = new HashMap<>();map.put("index",i);map.put("value",i*456/222);maps.add(map);}return maps;}
}

注意:如果报:org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type ...这种错误,表示没有找到json转换器,需要修改两个地方:

  1. 修改spring-mvc.xml,加上json转换器
<mvc:annotation-driven><mvc:message-converters><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/><bean class="org.springframework.http.converter.FormHttpMessageConverter"/><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg name="defaultCharset" value="UTF-8"/></bean></mvc:message-converters>
</mvc:annotation-driven>
  1. 添加jackson依赖
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.5</version>
</dependency>
  1. 在项目目录结构中将依赖jar包添到对应artifact的/WEB-INF/lib/下,重启tomcat即可!

8 拦截器

拦截器类似于servlet过滤器,与过滤器区别是:拦截器是AOP思想的应用

过滤器:任何java web工程都可以使用,配置了url-pattern为/*后可以进行资源过滤
拦截器:springmvc特有的,只拦截映射器中的请求,不拦截静态资源

定义拦截器:实现HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("请求处理前");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("请求处理后");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("请求完成清理资源");}
}

注意:重写的三个方法中,最重要的是第一个方法,如果返回值为false则请求被拦截!否则放行。
在srping-mvc.xml中配置拦截器:

<mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.xiaopi3.config.MyInterceptor"/></mvc:interceptor>
</mvc:interceptors>

注意:path为/**指拦截/下所有请求以及子请求!!
启动tomcat请求任意controller映射,返回结果:

请求处理前
执行业务逻辑代码----------
请求处理后
请求完成清理资源

8.1 拦截器Demo:登录拦截

环境:SpringMVC环境

  1. 首先编写页面:主页:index.jsp、展示页:users.jsp、登录页:login.jsp
主页:
<a href="${pageContext.request.contextPath}/user/findAll">进入用户展示页面</a>
<a href="${pageContext.request.contextPath}/goLogin">登录</a>用户展示页:
<a href="${pageContext.request.contextPath}/logout">注销</a>
<h1>用户展示</h1>登录页:
<form action="${pageContext.request.contextPath}/login" method="post">用户名:<input type="text" name="username"/>密码:<input type="password" name="password"/><input type="submit" value="提交">
</form>
  1. 编写登录拦截器
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("请求处理前");String uri = request.getRequestURI();System.out.println(uri);if(uri.contains("login")||uri.contains("goLogin")){return true;}if("true".equals(request.getSession().getAttribute("login"))){return true;}response.sendRedirect("/goLogin");return false;}
}

注意:这里注意三点:1. 用户访问登陆页面不需要拦截;2. 用户登陆页面请求登录不需要拦截;3. 已经登录后不需要拦截

  1. 注册拦截器到spring-mvc.xml
<mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.xiaopi3.config.MyInterceptor"/></mvc:interceptor>
</mvc:interceptors>

注意:可以在path中定义多级路径达到过滤部分路径不拦截的目的

  1. 编写controller
@Controller
public class LoginController {@RequestMapping("/goLogin")public String goLogin(){return "login";}@PostMapping("/login")public String login(HttpSession httpSession,String username,String password){if("xiaopi3".equals(username)&&"123456".equals(password)){httpSession.setAttribute("login","true");return "users";}return "login";}@RequestMapping("/logout")public String logout(HttpSession httpSession){httpSession.removeAttribute("login");return "redirect:/goLogin";}
}
  1. 启动tomcat测试效果:登录后可以进入内容展示页面,否则会跳转到登陆页面,注销后会跳转到登陆页面,并且需要登陆才能进入内容页。

9 文件上传

springmvc处理文件上传需要MultipartResolver

前端表单要求:为了能上传文件,必须将表单的method设置称POST,并将enctype设置为multipart/form-data,浏览器会以二进制流的方式来处理表单数据。apche发布的Commons FileUpload组件是Servlet/jsp最佳选择

  1. 导包
    注意:Springmvc将Commons FileUpload封装成了MultipartResolver,所以如果需要文件上传,下面两个包都需要
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
</dependency>
  1. 配置MultipartResolve
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--        must be same with jsp pageEncoding : default ISO-8859-1--><property name="defaultEncoding" value="utf-8"/>
<!--        unit:Byte 10M=10*1024*1024Byte--><property name="maxUploadSize" value="10485760"/><property name="maxInMemorySize" value="4096"/>
</bean>

注意:该id要求必须为:multipartResolver

  1. 配置Controller
@Controller
public class UploadController {@RequestMapping("/upload")public String upload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest httpServletRequest) throws IOException {// 获取文件名String uploadFileName = file.getOriginalFilename();// 如果文件名为空,则赋值默认:uploadif("".equals(uploadFileName)){return "users";}System.out.println("上传文件名:"+uploadFileName);// 上传路径String _path = httpServletRequest.getSession().getServletContext().getRealPath("/upload");System.out.println(_path);File path = new File(_path);if(!path.exists()){path.mkdir();}File _file = new File(path,uploadFileName);if(_file.exists()){String[] split = uploadFileName.split("\\.");uploadFileName = split[0] + UUID.randomUUID()+"."+split[1];_file = new File(path,uploadFileName);}InputStream inputStream = file.getInputStream();FileOutputStream fileOutputStream = new FileOutputStream(_file);int len=0;byte[] array = new byte[1024];while((len=inputStream.read(array))!=-1){fileOutputStream.write(array,0,len);}inputStream.close();fileOutputStream.close();return "users";}@RequestMapping("/upload2")public String upload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest httpServletRequest) throws IOException {// 获取文件名String uploadFileName = file.getOriginalFilename();// 如果文件名为空,则赋值默认:uploadif("".equals(uploadFileName)){return "users";}System.out.println("上传文件名:"+uploadFileName);// 上传路径String _path = httpServletRequest.getSession().getServletContext().getRealPath("/upload");System.out.println(_path);File path = new File(_path);if(!path.exists()){path.mkdir();}File _file = new File(path,uploadFileName);if(_file.exists()){String[] split = uploadFileName.split("\\.");uploadFileName = split[0] + UUID.randomUUID()+"."+split[1];_file = new File(path,uploadFileName);}// 通过CommonsMultipartFile方法直接写文件file.transferTo(_file);return "users";}
}

注意:两种方法的效果一样,不同之处在于IO流部分,第二种方式使用Springmvc包装好的方法transferTo进行文件写出。当没有选择文件之间点上传时,文件名为空,所以可以依此判断进行跳转。如果使用RestController可以使用ajax进行异步请求。

特别注意:参数输入部分:@RequestParam("file") CommonsMultipartFile file必须带上注解进行指定,否则报空指针异常!!

SpringMVC复习——B站相关推荐

  1. 基于sqlserver的数据库复习

    20220711 -20220724 数据库复习 + B站视频(基于sqlserver) 边看视频边随手记录的,可读性可能不太高,自用吧. 一. 1.为何要连接到数据库:数据库软件不是数据库,我们只是 ...

  2. 【记vue项目中的踩坑日记】一杯茶一包烟,一个bug搞一天

    昨天在复习B站coderwhy老师的项目时,偶然发现了一个问题,弄了半天,最后才发现问题出在哪. 封装完底部的导航栏之后实现路由跳转出现了问题,在浏览器中既不报错,也不输出内容,路由跳转也没有用 整了 ...

  3. redis发布订阅与集群

    本系列根据狂神说Redis写下笔记以供复习 B站狂神说Redis!:https://www.bilibili.com/video/BV1S54y1R7SB 发布订阅 Redis 发布订阅(pub/su ...

  4. 《如何在大学里脱颖而出(How to Win at College)》读书笔记

    <如何在大学里脱颖而出(How to Win at College)>读书笔记 图书简介 中文版: 英文版: 作者卡尔·纽波特(Cal Newport)于 2004 年6月以优等生荣誉学会 ...

  5. 中科大凌青老师凸优化课程——目录

    视频链接: 中科大-凸优化_哔哩哔哩_bilibili 课程对应目录: 1-2:推荐书目,引言,常见例子,优化问题分类,发展史 3-4:仿射/凸/凸锥 + 集/组合/包 5-6:几种重要的凸集:超平面 ...

  6. 2019年末逆向复习系列之淘宝M站Sign参数逆向分析

    郑重声明:本项目的所有代码和相关文章, 仅用于经验技术交流分享,禁止将相关技术应用到不正当途径,因为滥用技术产生的风险与本人无关. 这篇文章是<2019年末逆向复习系列>的第一篇:< ...

  7. b站尚硅谷springmvc学习视频:springmvc文档

    文章目录 一.SpringMVC简介 (b站尚硅谷springmvc学习视频:springmvc文档) 1.什么是MVC 2.什么是SpringMVC 3.SpringMVC的特点 二.HelloWo ...

  8. 【脱产二站上岸】上海交大819复习经验总结

    笔者来自通信考研小马哥23上交819全程班学员 本科西南某985,成绩排名中下(面试被老师疯狂吐槽),一战本校,初试分数差10来分被刷.21年12月考完数学和专业课出来就知道考不上了,分数一出就下决心 ...

  9. SpringMVC总复习

    SpringMVC课堂笔记1.SpringMVC概述 SpringMVC概念 SpringMVC 也叫 Spring web mvc.是 Spring内置的一个MVC框架,在 Spring3.0 后发 ...

  10. 一篇复习一下Spring和SpringMVC基本概念

    什么是Spring,为什么你要学习spring? 你第一次接触spring框架是在什么时候?相信很多人和我一样,第一次了解spring都不是做项目的时候用到,而是在网上看到或者是听到过一个叫做spri ...

最新文章

  1. 安装Ruby和Rails运行环境
  2. 数据为什么要可视化?如何可视化?
  3. Android系统的体系结构、开发语言及源码结构
  4. 下载bilibli网站视频
  5. 秒杀系统 mysql_秒杀系统-介绍
  6. Linux下SHELL的PS1变量简介
  7. python学习--面向过程程序设计实例
  8. git生成SSH密钥提示ssh文件不存在-已解决
  9. BZOJ1431 : MLand
  10. 拓端tecdat|WinBUGS对多元随机波动率模型:贝叶斯估计与模型比较
  11. Rust:Programming Rust:所有权
  12. 如何让WPS像word一样使用快捷键打开MathType
  13. 内存映射文件原理(转载)
  14. CDH6.0.1环境Hadoop集群性能测试
  15. 十七点学完安全知识超级详细了解进程和病毒知识 转载
  16. nodejs实现分解质因数的算法
  17. 2022/10/10-10/15周报
  18. 一、在GPU上执行运算
  19. Keil无法跳转到(go to definition)函数定义的地方,而是出现Browser
  20. 买笔记本电脑的13个重要的验机步骤

热门文章

  1. AutoIt 脚本流行编辑工具
  2. python 计算置信区间,Python求解正态分布置信区间
  3. the old reader使用分享
  4. ZOJ 3551 Bloodsucker(概率)
  5. 《丑奴儿书博山道中壁》
  6. 教你制作QQ空间超高连通率背景音乐链接。
  7. 在d盘创建文件夹,里面有aaa.txt/bbb.txt/ccc.txt,然后遍历出aaa文件夹下的文件(新手用于记录每天的作业)...
  8. 枕头Python 3
  9. mac电脑显示器分辨率显示异常
  10. php论坛整合,phpcms+ucenter+discuz论坛整合教程