SpringMVC-全面详解(学习总结---从入门到深化)

news2024/11/26 12:16:20

目录

 SpringMVC简介

 MVC模型

 SpringMVC

SpringMVC入门案例

SpringMVC执行流程 

 SpringMVC的组件

组件的工作流程 

SpringMVC参数获取_封装为简单数据类型

SpringMVC参数获取_封装为对象类型 

封装单个对象

封装关联对象 

SpringMVC参数获取_封装为集合类型 

封装为List集合

封装为简单数据类型集合

封装为对象类型集合 

封装为Map集合 

SpringMVC参数获取_使用Servlet原生对象获取参数 

 SpringMVC参数获取_自定义参数类型转换器

SpringMVC参数获取_编码过滤器 

SpringMVC处理响应_配置视图解析器

SpringMVC处理响应_控制器方法的返回值

SpringMVC处理响应_request域设置数据 

SpringMVC处理响应_session域设置数据

SpringMVC处理响应_context域设置数据

SpringMVC处理响应_请求转发&重定向 

SpringMVC的常用注解:

 SpringMVC注解_@Controller

 SpringMVC注解_@RequestMapping

SpringMVC注解_@RequestParam

 SpringMVC注解_@RequestHeader、@CookieValue

@RequestHeader

 @CookieValue

 SpringMVC注解_@SessionAttributes

SpringMVC注解_@ModelAttribute  

 SpringMVC注解_RESTful风格支持

RESTful风格介绍

Postman使用 

@PathVariable

@PostMapping、@GetMapping、@PutMapping、 @DeleteMapping 

HiddentHttpMethodFilter 

 SpringMVC注解_@ResponseBody

 SpringMVC注解_@RestController

静态资源映射

SpringMVC注解_@RequestBody 

SpringMVC文件上传_原生方式上传 

 SpringMVC文件上传_SpringMVC方式上传

 SpringMVC文件上传_上传多文件

 SpringMVC文件上传_异步上传

SpringMVC文件上传_跨服务器上传 

SpringMVC文件上传_文件下载 

SpringMVC异常处理_单个控制器异常处理

SpringMVC异常处理_全局异常处理

 SpringMVC异常处理_自定义异常处理器

SpringMVC拦截器_拦截器简介

 SpringMVC拦截器_拦截器使用

SpringMVC拦截器_全局拦截器 

 SpringMVC拦截器_拦截器链与执行顺序

SpringMVC拦截器_拦截器过滤敏感词案例 

SpringMVC跨域请求_同源策略 

SpringMVC跨域请求_跨域请求 

 SpringMVC跨域请求_控制器接收跨域请求

SSM整合_需求分析

 SSM整合_创建父工程

SSM整合_创建dao子工程

SSM整合_创建service子工程 

SSM整合_创建controller子工程 

SSM整合_运行项目 

 SpringMVC简介

 MVC模型

MVC全称Model View Controller,是一种设计创建Web应用程序的 模式。这三个单词分别代表Web应用程序的三个部分:

Model(模型):指数据模型。用于存储数据以及处理用户请求 的业务逻辑。在Web应用中,JavaBean对象,业务模型等都属 于Model。

View(视图):用于展示模型中的数据的,一般为jsp或html文 件。

Controller(控制器):是应用程序中处理用户交互的部分。接 受视图提出的请求,将数据交给模型处理,并将处理后的结果交 给视图显示。

 SpringMVC

SpringMVC是一个基于MVC模式的轻量级Web框架,是Spring框架 的一个模块,和Spring可以直接整合使用。SpringMVC代替了 Servlet技术,它通过一套注解,让一个简单的Java类成为处理请求 的控制器,而无须实现任何接口。

SpringMVC入门案例

 接下来我们编写一个SpringMVC的入门案例

1、使用maven创建web项目,补齐包结构。

2、引入相关依赖和tomcat插件

<dependencies>
    <!-- Spring核心模块 -->
    <dependency>
      <groupId>org.springframework</groupId>
        <artifactId>springcontext</artifactId>
        <version>5.2.12.RELEASE</version>
    </dependency>
    <!-- SpringWeb模块 -->
    <dependency>
      <groupId>org.springframework</groupId>
        <artifactId>springweb</artifactId>
        <version>5.2.12.RELEASE</version>
    </dependency>
    <!-- SpringMVC模块 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>springwebmvc</artifactId>
        <version>5.2.12.RELEASE</version>
    </dependency>
    <!-- Servlet -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servletapi</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <!-- JSP -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
 </dependencies>
<build>
    <plugins>
        <!-- tomcat插件 -->
        <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <port>8080</port>
                <path>/</path>
                <uriEncoding>UTF8</uriEncoding>
                <server>tomcat7</server>
                <systemProperties>
                  <java.util.logging.SimpleFormatter.format>%1$tH:%1$tM:%1$tS %2$s%n%4$s: %5$s%6$s%n
                  </java.util.logging.SimpleFormatter.format>
                </systemProperties>
            </configuration>
        </plugin>
    </plugins>
</build>

3、在web.xml中配置前端控制器DispatcherServlet。

<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <!--SpringMVC前端控制器,本质是一个 Servlet,接收所有请求,在容器启动时就会加载-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</paramvalue>
        </init-param>
        <load-on-startup>1</load-onstartup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4 编写SpringMVC核心配置文件springmvc.xml,该文件和Spring 配置文件写法一样。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:context="http://www.springframework.org/schema/context"
      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
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描包 -->
    <context:component-scan base-package="com.itbaizhan"/>
    <!-- 开启SpringMVC注解的支持 -->
    <mvc:annotation-driven/>
</beans>

5、编写控制器

@Controller
public class MyController1 {
    // 该方法的访问路径是/c1/hello1
    @RequestMapping("/c1/hello1")
    public void helloMVC(){
        System.out.println("hello SpringMVC!");
   }
}

6 使用tomcat插件启动项目,访问 http://localhost:8080/c1/hello1

SpringMVC执行流程 

 SpringMVC的组件

DispatcherServlet:前端控制器,接受所有请求,调用其他组件。

HandlerMapping:处理器映射器,根据配置找到方法的执行链。

HandlerAdapter:处理器适配器,根据方法类型找到对应的处理器。

ViewResolver:视图解析器,找到指定视图。

组件的工作流程 

1、客户端将请求发送给前端控制器。

2、前端控制器将请求发送给处理器映射器,处理器映射器根据路径找到方法的执行链,返回给前端控 制器。

3、前端控制器将方法的执行链发送给处理器适配器,处理器适配器根据方法类型找到对应的处理器。

4、处理器执行方法,将结果返回给前端控制器。

5、前端控制器将结果发送给视图解析器,视图解析器找到视图文件位置。

6、视图渲染数据并将结果显示到客户端。

SpringMVC参数获取_封装为简单数据类型

 

 在Servlet中我们通过 request.getParameter(name) 获取请求参数。该方式存 在两个问题:

 1、请求参数较多时会出现代码冗余。

 2、与容器紧耦合。

而SpringMVC支持参数注入的方式用于获取请求数据,即将请求参 数直接封装到方法的参数当中。用法如下:

 1、编写控制器方法

// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){
    System.out.println(username);
    System.out.println(age);
}

2、访问该方法时,请求参数名和方法参数名相同,即可完成自动封装。

SpringMVC参数获取_封装为对象类型 

 SpringMVC支持将参数直接封装为对象,写法如下:

封装单个对象

1、编写实体类

public class Student {
    private int id;
    private String name;
    private String sex;
    // 省略getter/setter/tostring
}

2、编写控制器方法

// 获取对象类型参数
@RequestMapping("/c1/param2")
public void objParam(Student student){
    System.out.println(student);
}

3、访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。

封装关联对象 

1、编写实体类

public class Address {
    private String info; //地址信息
    private String postcode; //邮编
    // 省略getter/setter/tostring
}
public class Student {
    private int id;
    private String name;
    private String sex;
    private Address address; // 地址对象
    // 省略getter/setter/tostring
}

2、编写控制器方法

// 获取关联对象类型参数
@RequestMapping("/c1/param3")
public void objParam2(Student student){  
    System.out.println(student);
}

3、访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。

我们也可以使用表单发送带有参数的请求:

<%@ page
contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
     <title>表单提交</title>
</head>
<body>
     <form action="/c1/param3" method="post">
         id:<input name="id">
         姓名:<input name="name">
         性别:<input name="sex">
         住址:<input name="address.info">
         邮编:<input name="address.postcode">
         <input type="submit">
     </form>
 </body>
</html>

SpringMVC参数获取_封装为集合类型 

 SpringMVC支持将参数封装为List或Map集合,写法如下:

封装为List集合

封装为简单数据类型集合

1、编写控制器方法

// 绑定简单数据类型List参数,参数前必须添加
@RequestParam注解
@RequestMapping("/c1/param4")
public void listParam(@RequestParamList<String> users){
    System.out.println(users);
}

该方式也可以绑定数组类型:

@RequestMapping("/c1/param5")
public void listParam2(@RequestParam String[] users){
    System.out.println(users[0]);
    System.out.println(users[1]);
}

2、请求的参数写法

封装为对象类型集合 

SpringMVC不支持将参数封装为对象类型的List集合,但可以封装 到有List属性的对象中。

1、编写实体类

public class Student {
    private int id;
    private String name;
    private String sex;
    private List<Address> address; // 地址集合
    // 省略getter/setter/tostring
}

2、编写控制器方法

// 对象中包含集合属性
@RequestMapping("/c1/param6")
public void listParam3(Student student){
    System.out.println(student);
}

3、请求的参数写法

封装为Map集合 

同样,SpringMVC要封装Map集合,需要封装到有Map属性的对象中。

1、编写实体类

public class Student {
    private int id;
    private String name;
    private String sex;
    private Map<String,Address> address;
    // 地址集合
    // 省略getter/setter/tostring
}

2、编写控制器方法

// 对象中包含Map属性
@RequestMapping("/c1/param7")
public void mapParam(Student student){  
    System.out.println(student);
}

3、请求的参数写法

SpringMVC参数获取_使用Servlet原生对象获取参数 

 SpringMVC也支持使用Servlet原生对象,在方法参数中定义 HttpServletRequest HttpServletResponse HttpSession 等类型的参数即可直接在 方法中使用。

// 使用Servlet原生对象
@RequestMapping("/c1/param8")
public void servletParam(HttpServletRequest request, HttpServletResponse response,
HttpSession session){  
       // 原生对象获取参数      
       System.out.println(request.getParameter("name"));
       System.out.println(response.getCharacterEncoding());    
       System.out.println(session.getId());
}

访问该方法即可:http://localhost:8080/c1/param8?name=bjwan

一般情况下,在SpringMVC中都有对Servlet原生对象的方法的 替代,推荐使用SpringMVC的方式代替Servlet原生对象。 

 SpringMVC参数获取_自定义参数类型转换器

 前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器 将字符串参数转为需要的类型。如:

// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){
    System.out.println(username);    
    System.out.println(age);
}

请求路径:http://localhost:8080/c1/param1?username=bz&age =10

但在某些情况下,无法将字符串转为需要的类型,如:

@RequestMapping("/c1/param9")
public void dateParam(Date birthday){  
    System.out.println(birthday);
}

由于日期数据有很多种格式,SpringMVC没办法把所有格式的字符 串转换成日期类型。比如参数格式为 birthday=2025-01-01 时,SpringMVC 就无法解析参数。此时需要自定义参数类型转换器。

 1、定义类型转换器类,实现Converter接口

// 类型转换器必须实现Converter接口,两个泛型代表转换前的类型,转换后的类型
public class DateConverter implements Converter<String, Date> {
    /**
     * 转换方法
     * @param source 转换前的数据
     * @return 转换后的数据
     */
    @Override
    public Date convert(String source) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(source);
       } catch (ParseException e) {
            e.printStackTrace();
       }
        return date;
   }
}

2、注册类型转换器对象

<!-- 配置转换器工厂 -->
<bean id="dateConverter" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <!-- 转换器集合 -->
    <property name="converters">
        <set>
            <!-- 自定义转换器 -->
            <bean class="com.itbaizhan.converter.DateConverter"></bean>
        </set>
    </property>
</bean    
<!-- 使用转换器工厂 -->
<mvc:annotation-driven conversionservice="converterFactory">
</mvc:annotation-driven>

3、此时再访问http://localhost:8080/c1/param9?birthday=2025- 01-01时,SpringMVC即可将请求参数封装为Date类型的参数。

SpringMVC参数获取_编码过滤器 

 在传递参数时,tomcat8以上能处理get请求的中文乱码,但不能处 理post请求的中文乱码

1、编写jsp表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>编码过滤器</title>
    </head>
    <body>
        <form action="/cn/code" method="post">
           姓名:<input name="username">
            <input type="submit">
        </form>
    </body>
</html>

2、编写控制器方法

@RequestMapping("/cn/code")
public void code(String username){
    System.out.println(username);
}

SpringMVC提供了处理中文乱码的过滤器,在web.xml中配置该过 滤器即可解决中文乱码问题:

<!--SpringMVC中提供的字符编码过滤器,放在所有过滤器的最上方-->
<filter>
    <filter-name>encFilter</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>encFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

SpringMVC处理响应_配置视图解析器

 SpringMVC默认情况下会在控制器执行完成后跳转到视图页面,视 图解析器能找到相应的视图,之前的404异常就是由于没有配置视 图解析器导致找不到视图。

在SpringMVC中提供了13个视图解析器,用于支持不同的视图技术。InternalResourceViewResolver是SpringMVC的默认视图解析 器,用来解析JSP视图。

<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 视图前缀 -->
    <property name="prefix" value="/" />
    <!-- 视图后缀 -->
    <property name="suffix" value=".jsp" />
</bean>

SpringMVC处理响应_控制器方法的返回值

 我们可以通过控制器方法的返回值设置跳转的视图,控制器方法支 持以下返回值类型:

返回值为void

此时会跳转到名字是 前缀+方法路径名+后缀 的jsp页面

1、编写控制器方法

// 路径是helloMVC,方法执行完后会跳转到/helloMVC.jsp
@RequestMapping("/helloMVC")
public void helloMVC(){
    System.out.println("hello SpringMVC!");
}

2、编写helloMVC.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>MVC</title>
    </head>
    <body>
        <h1>欢迎来到SpringMVC</h1>
    </body>
</html>

返回值为String 

此时会跳转到名字是 前缀+返回值+后缀 的jsp页面

编写控制器方法

// 返回值为String
@RequestMapping("/c2/hello1")
public String helloMVC1(){
    System.out.println("hello SpringMVC!");
    // 方法执行完后会跳转到/helloMVC.jsp
    return "helloMVC";
}

返回值为ModelAndView

这是SpringMVC提供的对象,该对象可以向request域设置数据并 指定跳转的页面。该对象中包含Model对象和View对象。

1、Model:向request域中设置数据。

2、View:指定跳转的页面。

 1、编写控制器方法

// 返回值为ModelAndView
@RequestMapping("/c2/hello2")
public ModelAndView useMAV(){
    System.out.println("返回值类型为ModelAndView");
    // 1.创建ModelAndView对象
    ModelAndView modelAndView = new ModelAndView();
    // 2.获取Model对象,本质是一个Map
    Map<String, Object> model = modelAndView.getModel();
    // 3.使用Model对象向request域设置数据
    model.put("name","程序员");
    // 4.使用View对象设置跳转的路径为/baizhan.jsp
    modelAndView.setViewName("baizhan");
    return modelAndView;
}

2、编写jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<html>
    <head>
        <title>百千万</title>
    </head>
    <body>
        <h1>你好!${requestScope.name}</h1>
    </body>
</html>

3、修改web.xml命名空间,让jsp页面默认支持el表达式

<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/javaee
                            http://xmlns.jcp.org/xml/ns/javaee/webapp_3_1.xsd"
         version="3.1">
</web-app>

SpringMVC处理响应_request域设置数据 

 当控制器返回值为ModelAndView时我们可以向request域设置数 据,我们还有以下方法可以向request域设置数据:

使用原生的HttpServletRequest

@RequestMapping("/c2/hello3")
public String setRequestModel(HttpServletRequest request){
    request.setAttribute("username","面涂学堂");
    return "baizhan";
}

使用Model、ModelMap

SpringMVC提供了Model接口和ModelMap类,控制器方法添加这 两个类型的参数,使用该参数设置数据,该数据就会存到request域中。

@RequestMapping("/c2/hello4")
public String setRequestModel2(Model model, ModelMap modelMap){
    // 使用Model将数据存入request域
    // model.addAttribute("username","辛苦学堂");
    // 使用ModelMap将数据存入request域
    modelMap.addAttribute("username","辛苦学堂");
    return "baizhan";
}

使用Map集合

Model接口底层就是一个Map集合,我们可以给控制器方法设置 Map类型的参数,向Map中添加键值对,数据也会存到request域 中。

@RequestMapping("/c2/hello5")
public String setRequestModel3(Map map){
    map.put("username","辛苦学堂");
    return "baizhan";
}

SpringMVC处理响应_session域设置数据

 Session作用域表示在当前会话中有效。在SpringMVC中对于

 Session作用域传值,只能使用HttpSession对象来实现。

1、编写控制器方法

@RequestMapping("/c2/hello6")
public String setSeesionModel(HttpSession session){
    session.setAttribute("address","北京");
    return "baizhan";
}

2、编写jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<html>
    <head>
        <title>百战不败</title>
    </head>
    <body>
       <h1>你好!${requestScope.name}</h1>
       <h1>地址是!${sessionScope.address}</h1>
    </body>
</html>

SpringMVC处理响应_context域设置数据

 context作用域表示在整个应用范围都有效。在SpringMVC中对 context作用域传值,只能使用ServletContext对象来实现。但是该 对象不能直接注入到方法参数中,需要通过HttpSession对象获取。

1、编写控制器方法

@RequestMapping("/c2/hello7")
public String setContextModel(HttpSession session){
    ServletContext servletContext = session.getServletContext();
    servletContext.setAttribute("age",10);
    return "baizhan";
}

2、编写jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<html>
    <head>
        <title>百战不败</title>
    </head>
    <body>
        <h1>你好!${requestScope.name}</h1>
        <h1>地址是!${sessionScope.address}</h1>
        <h1>年纪是!${applicationScope.age}</h1>
    </body>
</html>

SpringMVC处理响应_请求转发&重定向 

 之前的案例,我们发现request域中的值可以传到jsp页面中,也就 是通过视图解析器跳转到视图的底层是请求转发。

如果我们跳转时不想使用视图解析器,可以使用原生 HttpServletRequest进行请求转发或HttpServletResponse进行重定向:

@RequestMapping("/c2/hello8")
public void myForward1(HttpServletRequest request, HttpServletResponse response)
throws Exception{
    request.setAttribute("name","辛苦学堂");
    // 请求转发
    // request.getRequestDispatcher("/c2/hello9").forward(request,response);
    // 原生重定向
    response.sendRedirect("/c2/hello9");
 }
@RequestMapping("/c2/hello9")
public void myForward2(HttpServletRequest request){
    System.out.println("hello");
    System.out.println(request.getAttribute("name"));
}

SpringMVC还提供了一种更简单的请求转发和重定向的写法:

@RequestMapping("/c2/hello10")
public String myForward3(HttpServletRequest request){
    request.setAttribute("name","辛苦学堂");
    // 请求转发
    return "forward:/c2/hello9";
    // 重定向
    // return "redirect:/c2/hello9";
}

SpringMVC通过注解来实现控制器的功能,接下来我们详细学习 SpringMVC的常用注解:

SpringMVC的常用注解:

 SpringMVC注解_@Controller

作用:标记控制器,将控制器交给Spring容器管理。

位置:类上方

 SpringMVC注解_@RequestMapping

 作用:给控制器方法设置请求路径

 位置:方法或类上方。用于类上,表示类中的所有控制器方法都是 以该地址作为父路径。

 属性:

         1、value/path:请求路径

         2、method:指定请求方式

         3、params:规定必须发送的请求参数

         4、headers:规定请求必须包含的请求头

@Controller
@RequestMapping("/c3")
public class MyController3 {
     /*
        访问路径为 /c3/annotation1
        支持post和get请求
        请求时必须带有age参数
        请求时必须带有User-agent请求头
     */
    @RequestMapping(path = "/annotation1",method =
{RequestMethod.GET,RequestMethod.POST},params = {"age"},headers = {"User-agent"})
    public String annotation1(String username){
        System.out.println(username);
        return "baizhan";
   }
}

SpringMVC注解_@RequestParam

 作用:在控制器方法中获取请求参数

 位置:方法参数前

 属性:

        1、name:指定请求参数名称

        2、defaultValue: 为参数设置默认值

        3、required:设置是否是必须要传入的参数

/*
    定义请求的参数名为username,默认值为sxt,不是必须的参数
*/
@RequestMapping("/annotation2")
public String annotation2(@RequestParam(name = "username",defaultValue = "sxt",required =
false) String name){
    System.out.println(name);
    return "baizhan";
}

 SpringMVC注解_@RequestHeader、@CookieValue

@RequestHeader

 作用:在控制器方法中获取请求头数据

 位置:方法参数前

 @CookieValue

作用:在控制器方法中获取Cookie数据

位置:方法参数前

/*
  获取User-Agent请求头
  获取JSESSIONID的Cookie值
 */
@RequestMapping("/annotation3")
public String annotation3(@RequestHeader("User-Agent")
String userAgent, @CookieValue("JSESSIONID") String jSessionId){
    System.out.println(userAgent);
    System.out.println(jSessionId);
    return "baizhan";
}

 SpringMVC注解_@SessionAttributes

 作用:将Model模型中的数据存到session域中

 位置:类上方

@Controller
@RequestMapping("/c4")
// 将模型中的name数据保存到session中
@SessionAttributes("name")
public class MyController4 {
    @RequestMapping("/t1")
    public String t1(Model model){
        // model中保存name数据
        model.addAttribute("name","北京大乱斗");
        return "baizhan";
   }
    @RequestMapping("/t2")
    public String t2(HttpSession session){
        // 从session中获取name数据
      System.out.println(session.getAttribute("name"));
        return "baizhan";
   }
}

SpringMVC注解_@ModelAttribute  

 

 作用1:设置指定方法在控制器其他方法前执行

 位置:方法上方

@Controller
@RequestMapping("/c5")
public class MyController5 {
    @ModelAttribute
    public void before(){
        System.out.println("前置方法");
   }
    @RequestMapping("/t1")
    public String t1(){
        System.out.println("t1");
        return "baizhan";
   }
}

作用2:从Model模型中获取数据给参数赋值

位置:方法参数前

@Controller
@RequestMapping("/c6")
public class MyController6 {
    // 前置方法向Model中设置数据
    @ModelAttribute
    public void before(Model model){
        model.addAttribute("name","辛苦学堂");
   }
    // 该参数不是从请求中获取,而是从Model中获取
    @RequestMapping("/t1")
    public String t1(@ModelAttribute("name") String name){
        System.out.println(name);
        return "baizhan";
   }
}

 SpringMVC注解_RESTful风格支持

RESTful风格介绍

RESTful风格是一种URL路径的设计风格。在RESTful风格的URL路 径中,网络上的任意数据都可以看成一个资源,它可以是一段文 本、一张图片,也可以是一个Java对象。而每个资源都会占据一个 网络路径,无论对该资源进行增删改查,访问的路径是一致的。

传统URL:

    查找id为1的学生: http://localhost:8080/student/findById?id=30

    删除id为1的学生: http://localhost:8080/student/deleteById?id=30

RESTful风格URL:

    查找id为30的学生: http://localhost:8080/student/30

    删除id为30的学生: http://localhost:8080/student/30

 那么如何区分对该资源是哪一种操作?通过请求方式不同,判断进 行的是什么操作。

之前我们学过两种请求方式,GET请求和POST请求,而访问 RESTful风格的URL一共有四种请求方式:

       1、GET请求:查询操作

       2、POST请求:新增操作

       3、DELETE请求:删除操作

       4、PUT请求:修改操作

RESTful风格URL:

       查找id为30的学生: http://localhost:8080/student/30 GET方式请求

       删除id为30的学生: http://localhost:8080/student/30 DELETE方式请求

RESTful风格的优点:

结构清晰、符合标准、易于理解、扩展方便。

Postman使用 

默认情况下浏览器是无法发送DELETE请求和PUT请求的,我们可以 使用Postman工具发送这些请求。

1、双击安装包安装Postman

2、点击new-collection创建请求集合

 3、添加请求

 4、保存请求到集合,以后可以随时发送该请求

@PathVariable

 

 作用:在RESTful风格的URL中获取占位符的值

 位置:方法参数前

 属性:

1、value:获取哪个占位符的值作为参数值,如果占位符和参数名相同,可以省略该属性。

@Controller
@RequestMapping("/student")
// 模拟学生的增删改查控制器
public class StudentController {
    // 路径中的{id}表示占位符,最后会封装到方法的参数中使用
    // 删除学生
    @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    public String deleteStudent(@PathVariable("id") int id){
        System.out.println("删除id为"+id+"的学生");
        return "baizhan";
}
    // 如果占位符和参数名相同,可以省略 @PathVariable的value属性
    // 根据id查询学生
    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    public String findStudentById(@PathVariable int id){
        System.out.println(id);
        System.out.println("根据id查询学生");
        return "baizhan";
   }
 // 新增学生
    @RequestMapping(value = "/{id}",method = RequestMethod.POST)
    public String addStudent(@PathVariable int id, Student student){
        System.out.println(id);
        System.out.println(student);
        System.out.println("新增学生");
        return "baizhan";
   }
    // 修改学生
    @RequestMapping(value = "/{id}",method = RequestMethod.PUT)
    public String updateStudent(@PathVariable int id, Student student){
        System.out.println(id);
        System.out.println(student);
        System.out.println("修改学生");
        return "baizhan";
   }
}

访问方式:

      新增学生:POST http://localhost:8080/student/1?name=辛苦学堂&sex=男

      修改学生:PUT http://localhost:8080/student/1?name=辛苦学堂&sex=男

      删除学生:DELETE http://localhost:8080/student/1

      查询学生:GET http://localhost:8080/student/1

@PostMapping、@GetMapping、@PutMapping、 @DeleteMapping 

作用:简化设置请求方式的@RequestMapping写法

位置:方法上方。

@Controller
@RequestMapping("/student")
public class StudentController {
    // 删除学生
    @DeleteMapping("/{id}")
    public String deleteStudent(@PathVariable("id") int id){
        System.out.println("删除id为"+id+"的学生");
        return "baizhan";
   }
    // 根据id查询学生
    @GetMapping("/{id}")
    public String findStudentById(@PathVariable int id){
        System.out.println(id);
        System.out.println("根据id查询学生");
        return "baizhan";
   }
    // 新增学生
    @PostMapping("/{id}")
    public String addStudent(@PathVariable int id, Student student){
        System.out.println(id);
        System.out.println(student);
        System.out.println("新增学生");
        return "baizhan";
   }
    // 修改学生
    @PutMapping("/{id}")
    public String updateStudent(@PathVariable int id, Student student){
        System.out.println(id);
        System.out.println(student);
        System.out.println("修改学生");
        return "baizhan";
   }
}

HiddentHttpMethodFilter 

 由于浏览器form表单只支持GET与POST请求,而DELETE、PUT请 求并不支持,SpringMVC有一个过滤器,可以将浏览器的POST请求 改为指定的请求方式,发送给的控制器方法。

用法如下:

1、在web.xml中配置过滤器

<!-- 请求方式过滤器 -->
<filter>
    <filter-name>httpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>httpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2、编写控制器方法

@Controller
@RequestMapping("/c7")
public class MyController7 {
    @DeleteMapping("/delete")
    public String testDelete(){
        System.out.println("删除方法");
        return "baizhan";
   }
    @PutMapping("/put")
    public String testPut(){
        System.out.println("修改方法");
        return "baizhan";
   }
}

3、在jsp中编写表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>DELETE、PUT提交</title>
    </head>
    <body>
        <!-- 删除 -->
       <%-- 提交DELETE、PUT请求,表单必须提交方式为post --%>
       <%-- 表单中有一个隐藏域,name值为 _method,value值为提交方式 --%>
       <form action="/c7/delete" method="post">
            <input type="hidden" name="_method" value="DELETE">
            <input type="submit" value="删除">
        </form>
        <hr/>
        <!-- 修改 -->
        <form action="/c7/put" method="post">
            <input type="hidden" name="_method" value="PUT">
            <input type="submit" value="修改">
        </form>
    </body>
</html>

 SpringMVC注解_@ResponseBody

 作用:方法返回的对象转换为JSON格式,并将JSON数据直接写入 到输出流中,使用此注解后不会再经过视图解析器。使用该注解可 以处理Ajax请求。

位置:方法上方或方法返回值前

1、编写jsp页面,发送ajax请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>ajax请求</title>
        <script src="/js/jquery-2.1.1.min.js"></script>
        <script>
            $(function () {$("#btn").click(function () {
                    var name = $("#name").val();
                    var sex = $("#sex").val();
                    $.get("/c8/addStudent", {"name":name,"sex":sex},function (data){
                        console.log(data);
                   });
               });
           });
        </script>
    </head>
    <body>
       姓名:<input id="name"/><br/>
       性别:<input id="sex"/><br/>
        <input type="button" value="提交" id="btn"/>
    </body>
</html>

2、由于jsp页面中引入jQuery的js文件,而SpringMVC会拦截所有 资源,造成jquery.js失效,需要在SpringMVC核心配置文件中放 行静态资源。

<!-- 放行静态资源 -->
<mvc:default-servlet-handler />

3、编写结果实体类,该实体类会封装一个请求的结果

// 请求的结果对象
public class Result {  
    private boolean flag; // 请求是否成功  
    private String message; // 请求提示信息 
    // 省略getter/setter/构造方法
}

4、编写控制器

@PostMapping("/addStudent")
@ResponseBody
public Result addStudent(String name, String sex) {
    // 输出接受到的参数,模拟添加学生
    System.out.println(name+":"+sex);
    // 返回添加结果
    Result result = new Result(true, "添加学生成功!");
    return result;
}

5、SpringMVC会将Result对象转为JSON格式写入输出流,而 SpringMVC默认使用的JSON转换器是jackson,需要在pom中添 加jackson依赖。

<!-- jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jacksondatabind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jacksonannotations</artifactId>
    <version>2.9.0</version>
</dependency>

 SpringMVC注解_@RestController

如果一个控制器类下的所有控制器方法都返回JSON格式数据且不进 行跳转,可以使用@RestController代替@Controller,此时每个方 法上的@ResponseBody都可以省略。

@RestController
@RequestMapping("/c8")
public class MyController8 {    
    @PostMapping("/addStudent")    
    public Result addStudent(String name, String sex) {
        // 输出接受到的参数,模拟添加学生      
        System.out.println(name+":"+sex);  
   
        // 返回结果        
        Result result = new Result(true, "添加学生成功!");
        return result;    
   }
}

静态资源映射

 当在DispatcherServlet的<url-pattern> 中配置拦截 “/” 时,除了jsp文件 不会拦截以外,其他所有的请求都会经过前端控制器进行匹配。此 时静态资源例如css、js、jpg等就会被前端控制器拦截,导致不能访 问,出现404问题。想要正常映射静态资源共有三种方案:

配置静态资源筛查器

在SpringMVC的配置文件中配置 后,会在Spring容器中创建一个资源检查器,它对进入 DispatcherServlet的URL进行筛查,如果不是静态资源,才由 DispatcherServlet处理。

修改SpringMVC核心配置文件:

<mvc:default-servlet-handler/>

配置静态资源映射器

SpringMVC模块提供了静态资源映射器组件,通过 标签 配置静态资源映射器,配置后的路径不会由DispatcherServlet处 理。

修改SpringMVC核心配置文件:

<!--配置静态资源映射器-->
<!-- mapping:配置请求的URL location:资源路径-->
<mvc:resources mapping="/img/" location="/img/"/><mvc:resources mapping="/js/" location="/js/"/>

配置默认Servlet处理静态资源

在web.xml可以配置默认Servlet处理静态资源,该Servlet由tomcat 提供,它会直接访问静态资源不进行其他操作。这样就避免了使用 DispatcherServlet对静态资源的拦截:

修改web.xml:

<servlet-mapping>    
    <servlet-name>default</servlet-name>  
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>    
    <servlet-name>default</servlet-name>  
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>    
    <servlet-name>default</servlet-name>  
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>    
    <servlet-name>default</servlet-name>  
    <url-pattern>*.png</url-pattern>
</servlet-mapping>

SpringMVC注解_@RequestBody 

 作用:将请求中JSON格式的参数转为JAVA对象

 位置:写在方法参数前

1、AJAX请求发送JSON格式的参数

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>ajax请求</title>
        <script src="/js/jquery2.1.1.min.js"></script>
        <script>
            $(function (){
                $("#btn").click(function(){
                    var name=$("#name").val();
                    var sex=$("#sex").val();
                    var param = JSON.stringify({"name":name,"sex":sex});
                    $.ajax({
                      url:"/c8/addStudent2",
                      contentType:"application/json",
                      type:"post",data:param,success:function(data){
                          console.log(data);
                       }
                   })
               })
           })
        </script>
    </head>
    <br>
       姓名:<input id="name"><br />
       性别:<input id="sex"><br />
       <input type="button" value="提交"id="btn">
    </body>
</html>

2、编写控制器

@PostMapping("/addStudent2")
@ResponseBody
public Result addStudent2(@RequestBody Student student) {
    System.out.println(student);
    // 返回添加结果
    Result result = new Result(true, "添加学生成功!");
    return result;
}

SpringMVC文件上传_原生方式上传 

 上传是Web工程中很常见的功能,SpringMVC框架简化了文件上传 的代码,我们首先使用JAVAEE原生方式上传文件:

1、创建新的SpringMVC项目,在web.xml中将项目从2.3改为3.1, 即可默认开启el表达式

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/webapp_3_1.xsd"
         id="WebApp_ID" version="3.1">

2、编写上传表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
   <title>上传</title>
    </head>
    <body>
        <h3>文件上传</h3>
       <%-- 上传表单的提交方式必须是post --%>
       <%-- enctype属性为multipart/formdata,意思是不对表单数据进行编码 --%>
        <form action="/fileUpload" method="post" enctype="multipart/formdata">
           <%-- 文件选择控件,类型是file,必须要有name属性--%>
           选择文件:<input type="file"name="upload"/>
            <input type="submit" value="上传"/>
        </form>
    </body>
</html>

3、接收请求体数据:

@RequestMapping("/fileUpload")
public String upload(HttpServletRequest request) throws Exception {
    // 获取输入流
    ServletInputStream is = request.getInputStream();
    // 从输入流获取请求体数据
    int i = 0;
    while ((i=is.read())!=-1){
        System.out.println((char)i);
   }
    return "index";
}

接下来需要分析请求体中的文件项,并将数据写入磁盘,此时需要 借助文件上传工具

 1、引入文件上传依赖:

<!-- 文件上传 -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commonsfileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

2、编写控制器接收上传请求,控制器进行三步操作:

     2.1 创建文件夹,存放上传文件。

     2.2 分析请求体,找到上传文件数据。

     2.3 将文件数据写入文件夹。

@RequestMapping("/fileUpload")
public String upload(HttpServletRequest request) throws Exception {
    // 创建文件夹,存放上传文件
    // 1.设置上传文件夹的真实路径
    String realPath = request.getSession().getServletContext().getRealPath("/upload");
    // 2.判断该目录是否存在,如果不存在,创建该目录
    File file = new File(realPath);
    if(!file.exists()){
        file.mkdirs();
   }
    // 分析请求体,找到上传文件数据
    // 1.创建磁盘文件工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    // 2.创建上传数据分析器对象
    ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
    // 3.利用分析器对象解析请求体,返回所有数据项
    List<FileItem> fileItems = servletFileUpload.parseRequest(request);
    // 4.遍历所有数据,找到文件项(非表单项)
    for (FileItem fileItem:fileItems){
        if(!fileItem.isFormField()){
            // 将文件数据写入文件夹
            // 1.获取文件名
            String name = fileItem.getName();
            // 2.将文件写入磁盘
            fileItem.write(new File(file,name));
            // 3.删除内存中的临时文件
            fileItem.delete();
       }
   }
    return "index";
}

 SpringMVC文件上传_SpringMVC方式上传

 SpringMVC使用框架提供的文件解析器对象,可以直接将请求体中 的文件数据转为MultipartFile对象,从而省略原生上传中分析请求体的步骤。

1、在SpringMVC核心配置文件配置文件解析器

<!-- 文件解析器对象,id名称必须是 multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 支持一次上传文件的总容量。单位:字节 100M = 100*1024*1024-->
    <property name="maxUploadSize" value="104857600"/>
    <!-- 文件名的编码方式-->
    <property name="defaultEncoding" value="utf-8"/>
</bean>

2、创建JSP表单

<form action="/fileUpload2" method="post" enctype="multipart/form-data">
    <input type="file" name="file"/>
    <input type="submit" value="上传"/>
</form>

3、编写控制器接收上传请求

// MultipartFile参数名必须和JSP文件空间的name
属性一致
@RequestMapping("/fileUpload2")
public String upload2(MultipartFile file,HttpServletRequest request) throws IOException {
    // 创建文件夹,存放上传文件
    String realPath = request.getSession().getServletContext().getRealPath("/upload");
    File dir = new File(realPath);
    if(!dir.exists()){
        dir.mkdirs();
   }
    // 将上传的数据写到文件夹的文件中
    // 1.拿到上传的文件名
    String filename = file.getOriginalFilename();
    filename = UUID.randomUUID()+"_"+filename;
    // 2.创建空文件
    File newFile = new File(dir,filename);
    // 3.将数据写入空文件中
    file.transferTo(newFile);
    return "index";
}

 SpringMVC文件上传_上传多文件

SpringMVC支持一次性上传多个文件,写法如下:

1、创建JSP表单

<form action="/fileUpload3" method="post" enctype="multipart/form-data">
   用户名:<input name="username"/>
   文件1:<input type="file" name="files"/>
   文件2:<input type="file" name="files"/>
    <input type="submit" value="上传"/>
</form>

2、编写控制器接收上传请求

// 处理多文件上传,参数类型为MultipartFile数组,参数名和JSP文件控件的name属性一致
@RequestMapping("/fileUpload3")
public String upload3(MultipartFile files[],String username,HttpServletRequest request) throws Exception {
    System.out.println(username);
    //1.设置上传文件保存的文件夹
    String realPath =request.getSession().getServletContext().getRealPath("/upload");
    File dir = new File(realPath);
    if (!dir.exists()){
        dir.mkdirs();
   }
    //2.遍历数组,将上传文件保存到文件夹
    for(MultipartFile file:files){
        String filename =file.getOriginalFilename();
        filename =UUID.randomUUID()+"_"+filename;
        File newFile = new File(dir,filename);
        file.transferTo(newFile);
   }
    return "index";
}

 SpringMVC文件上传_异步上传

 之前的上传方案,在上传成功后都会跳转页面。而在实际开发中, 很多情况下上传后不进行跳转,而是进行页面的局部刷新,比如: 上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。

1、编写JSP页面,引入jQuery和jQuery表单上传工具

      jquery.form.js

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>上传</title>
    <script src="/js/jquery-2.1.1.min.js"></script>
    <script src="/js/jquery.form.js">
</script>
</head>
<body>
<h3>文件上传</h3>
<form id="ajaxForm" enctype="multipart/form-data" >
    <input type="file" name="file"/>
   <%-- 按钮类型不能是submit,否则会刷新页面  --%>
    <input type="button" value="上传头像"id="btn"/>
</form>
<%-- 上传头像后展示的位置 --%>
<img src="/" width="100" id="img">
<script>
    $(function () {
        $("#btn").click(function () {
            // 异步提交表单
            $("#ajaxForm").ajaxSubmit({
                url:"/fileUpload4",
                type:"post",
                success:function (data) {
                  $("#img").attr("src",data);
               }
           })
       })
   })
</script>
</body>
</html>

2、编写控制器接收异步上传请求

@RequestMapping("/fileUpload4")
//不进行页面跳转
@ResponseBody
public String upload3(HttpServletRequest request, MultipartFile file) throws Exception {
    // 创建文件夹,存放上传文件。
    String realPath = request.getSession().getServletContext().getRealPath("/upload");
    File dir = new File(realPath);
    if (!dir.exists()){
        dir.mkdirs();
   }
    // 拿到上传文件名
    String filename = file.getOriginalFilename();
    filename = UUID.randomUUID()+"_"+filename;
    // 创建空文件
    File newFile = new File(dir, filename);
    // 将上传的文件写到空文件中
    file.transferTo(newFile);
    // 返回文件的路径
    return "/upload/"+filename;
}

SpringMVC文件上传_跨服务器上传 

 由于文件占据磁盘空间较大,在实际开发中往往会将文件上传到其 他服务器中,此时需要使用跨服务器上传文件。

1、解压tomcat作为图片服务器,在tomcat的webapps下创建 upload目录作为文件上传目录。

2、修改tomcat的 conf/web.xml 文件,支持跨服上传。

<servlet>    
    <init-param>        
        <param-name>readonly</param-name>
   
        <param-value>false</param-value>  
    </init-param>
</servlet>

3、修改tomcat的 conf/server.xml 文件,修改tomcat端口,修改完开启 tomcat服务器

<Connector port="8081" protocol="HTTP/1.1"
              connectionTimeout="20000" redirectPort="8443" />

4、编写JSP上传表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>上传</title>
        <script src="/js/jquery2.1.1.min.js"></script>
        <script src="/js/jquery.form.js"></script>
    </head>
    <body>
        <h3>文件上传</h3>
        <form id="ajaxForm" enctype="multipart/form-data" >
            <input type="file" name="file"/>
            <input type="button" value="上传头像" id="btn"/>
        </form>
        <img src="/" width="100" id="img">
        <script>
            $(function () {
                $("#btn").click(function() {
                  $("#ajaxForm").ajaxSubmit({url:"/fileUpload5",
                        type:"post",success:function(data) {
                          $("#img").attr("src",data);
                       }
                   })
               })
           })
        </script>
    </body>
</html>

5、添加跨服上传依赖

<!-- 跨服上传 -->
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-core</artifactId>
    <version>1.18.1</version>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.18.1</version>
</dependency>

6、创建控制器方法,该方法在接受到上传请求后将文件保存到其他服务器上。

@RequestMapping("/fileUpload5")
@ResponseBody
public String upload4(HttpServletRequest request, MultipartFile file) throws Exception {
    // 设置跨服上传的服务器路径
    String path = "http://localhost:8081/upload/";
    // 获取上传的文件名
    String filename = file.getOriginalFilename();
    filename = UUID.randomUUID()+"_"+filename;
    // 跨服上传:
    // 1.创建客户端对象
    Client client = Client.create();
    // 2.使用客户端对象连接图片服务器
    WebResource resource = client.resource(path + filename);
    //3.传输数据
    resource.put(file.getBytes());
    return path+filename;
}

SpringMVC文件上传_文件下载 

将文件上传到服务器后,有时我们需要让用户下载上传的文件,接下来我们编写文件下载功能:

查询所有可下载的文件

1、编写控制器方法,查询所有可下载的文件,并跳转到下载页面

// 查询可下载的文件
@RequestMapping("/showFiles")
public String showFileDown(HttpServletRequest request, Model model){
    //1.获取下载文件路径集合。注:跨服务器上传中,网络路径无法获取文件列表。
    String path = request.getSession().getServletContext().getRealPath("/upload");
    File file = new File(path);
    String[] files = file.list();
    //2.将路径放入模型中,跳转到JSP页面
    model.addAttribute("files",files);
    return "download";
}

2、添加JSTL依赖

<!-- JSTL -->
<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-spec</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-impl</artifactId>
    <version>1.2.5</version>
</dependency>

3、编写下载页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <head>
        <title>下载</title>
    </head>
    <body>
        <h3>文件下载</h3>
       <%-- 遍历文件集合 --%>
        <c:forEach items="${files}" var="file">
            <a href="/download?fileName=${file}">${file}</a><br/>
        </c:forEach>
    </body>
</html>

编写下载控制器 

// 文件下载
@RequestMapping("/download")
public void fileDown(HttpServletRequest request, HttpServletResponse response,String fileName) throws IOException {
    // 设置响应头
    response.setHeader("ContentDisposition","attachment;filename="+fileName
);
 // 获取文件路径
    String path = request.getSession().getServletContext().getRealPath("/upload");
    File file = new File(path,fileName);
    // 获取字节输出流
    ServletOutputStream os = response.getOutputStream();
    // 使用输出流写出文件
    os.write(FileUtils.readFileToByteArray(file));
    os.flush();
    os.close();
}

SpringMVC异常处理_单个控制器异常处理

 在系统当中, Dao、Service、Controller层代码出现都可能抛出异 常。如果哪里产生异常就在哪里处理,则会降低开发效率。所以一 般情况下我们会让异常向上抛出,最终到达DispatcherServlet中, 此时SpringMVC提供了异常处理器进行异常处理,这样可以提高开发效率。

 处理单个Controller的异常:

@Controller
public class MyController {
    @RequestMapping("/t1")
    public String t1(){
        String str = null;
        //       str.length();
        //       int flag = 1/0;
        int[] arr = new int[1];
        arr[2] = 10;
        return "index";
   }
    /**
     * 异常处理方法
     * @param ex 异常对象
     * @param model 模型对象
     * @return
     */
    // 添加@ExceptionHandler,表示该方法是处理异常的方法,属性为处理的异常类
  @ExceptionHandler({java.lang.NullPointerException.class,java.lang.ArithmeticException.c
lass})
public String exceptionHandle1(Exception ex, Model model){
        // 向模型中添加异常对象
        model.addAttribute("msg",ex);
        // 跳转到异常页面
        return "error";
   }
    // 方法一不能处理的异常交给方法二处理
  @ExceptionHandler(java.lang.Exception.class)
    public String exceptionHandle2(Exception ex, Model model){
        model.addAttribute("msg",ex);
        return "error2";
   }
}

异常页面error.jsp

<%@ page contentType="text/html;charset=UTF8" language="java" %>
<html>
    <head>
        <title>出错了!</title>
    </head>
    <body>
        <h3>ERROR 发生异常!${msg}</h3>
    </body>
</html>

异常页面error2.jsp

<%@ page contentType="text/html;charset=UTF8" language="java" %>
<html>
    <head>
        <title>出错了!</title>
    </head>
    <body>
        <h3>ERROR2 发生严重异常!${msg}</h3>
    </body>
</html>

SpringMVC异常处理_全局异常处理

 在控制器中定义异常处理方法只能处理该控制器类的异常,要想处 理所有控制器的异常,需要定义全局异常处理类。

1、编写另一个有异常的控制器类

@Controller
public class MyController2 {
    @RequestMapping("/t2")
    public String t2(){
        int[] arr = new int[1];
        arr[2] = 10;
        return "index";
   }
}

2、编写全局异常处理器类

// 全局异常处理器类,需要添加@ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
    /*** 异常处理方法
     *
     * @param ex   异常对象
     * @param model 模型对象
     * @return
     */
    // 添加@ExceptionHandler,表示该方法是处 理异常的方法,属性为处理的异常类
    @ExceptionHandler({java.lang.NullPointerException.class,java.lang.ArithmeticException.class})
    public String exceptionHandle1(Exception ex, Model model) {
        // 向模型中添加异常对象
        model.addAttribute("msg", ex);
        // 跳转到异常页面
        return "error";
   }
    // 方法一不能处理的异常交给方法二处理
    @ExceptionHandler(java.lang.Exception.class)
    public String exceptionHandle2(Exception ex, Model model) {
        model.addAttribute("msg", ex);
        return "error2";
   }
}

 SpringMVC异常处理_自定义异常处理器

 以上方式都是使用的SpringMVC自带的异常处理器进行异常处理, 我们还可以自定义异常处理器处理异常:

// 自定义异常处理器实现HandlerExceptionResolver接口,并放入Spring容器中
@Component
public class MyExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e)
{
        ModelAndView modelAndView = new ModelAndView();
        if (e instanceof NullPointerException) {
          modelAndView.setViewName("error");
       } else {
          modelAndView.setViewName("error2");
       }
        modelAndView.addObject("msg", e);
        return modelAndView;
   }
}

SpringMVC拦截器_拦截器简介

SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方 式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的 请求并做相应的处理,通常应用在权限验证、记录请求信息的日 志、判断用户是否登录等功能上。

拦截器和过滤器的区别

拦截器是SpringMVC组件,而过滤器是Servlet组件。

拦截器不依赖Web容器,过滤器依赖Web容器。

拦截器只能对控制器请求起作用,而过滤器则可以对所有的请求起作用。

拦截器可以直接获取IOC容器中的对象,而过滤器就不太方便获取。

 SpringMVC拦截器_拦截器使用

 接下来我们使用SpringMVC拦截器

1、使用maven创建SprinMVC的web项目

2、创建控制器方法

@RequestMapping("/m1")
public String m1(){
    System.out.println("控制器方法");
    return "result";
}

3、创建拦截器类,该类实现HandlerInterceptor接口,需要重写三个方法:

3.1 preHandle:请求到达Controller前执行的方法,返回值为true通过拦截器,返回值为false被 拦截器拦截。

3.2 postHandle:跳转到JSP前执行的方法

3.3 afterCompletion:跳转到JSP后执行的方法  

// 拦截器类
public class MyInterceptor implements HandlerInterceptor {
    // 请求到达Controller前执行
    @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object
handler) {
        System.out.println("请求到达 Controller前");
        // 如果return false则无法到达 Controller
        return true;
   }
    // 跳转到JSP前执行,此时可以向Request域添加数据
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("跳转到JSP前");
        request.setAttribute("name","百战不败");
   }
    // 跳转到JSP后执行,此时已经不能向Request域添加数据
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
        System.out.println("跳转到JSP后");
        request.setAttribute("age",10);
   }
}

4、编写JSP页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>结果</title>
    </head>
    <body>
        <h3>name:${requestScope.name}</h3>
        <h3>age:${requestScope.age}</h3>
    </body>
</html>

5、在SpringMVC核心配置文件中配置拦截器

<!-- 配置拦截器-->
<mvc:interceptors>  
    <mvc:interceptor>        
        <!-- 配置拦截器的作用路径-->      
        <mvc:mapping path="/**"/>        
        <!-- 拦截器对象 -->      
        <bean class="com.itbaizhan.interceptor.MyInterceptor"/>  
    </mvc:interceptor>
</mvc:interceptors>

SpringMVC拦截器_全局拦截器 

全局拦截器可以拦截所有控制器处理的URL,作用等于/**,配置方 式如下:

<!-- 配置拦截器 -->
<mvc:interceptors>  
    <!-- 全局拦截器 -->    
    <bean class="com.itbaizhan.interceptor.MyInterceptor"></bean>
</mvc:interceptors>

 SpringMVC拦截器_拦截器链与执行顺序

 如果一个URL能够被多个拦截器所拦截,全局拦截器最先执行,其 他拦截器根据配置文件中配置的从上到下执行,接下来我们再配置 一个拦截器:

1、编写拦截器类

public class MyInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) {
        System.out.println("拦截器2:请求到达Controller前");
        return true;
   }
    @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) {
        System.out.println("拦截器2:跳转到JSP前");
   }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) {
        System.out.println("拦截器2:跳转到JSP后");
   }
}

2、配置拦截器链

<!-- 配置拦截器 -->
<mvc:interceptors>
    <!-- 拦截器1 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.itbaizhan.interceptor.MyInterceptor"/>
    </mvc:interceptor>
    <!-- 拦截器2 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.itbaizhan.interceptor.MyInterceptor2"/>
    </mvc:interceptor>
</mvc:interceptors>

 

SpringMVC拦截器_拦截器过滤敏感词案例 

 接下来我们编写一个拦截器案例,需求如下: 在系统中,我们需要将所有响应中的一些敏感词替换为 *** ,此时可以使用拦截器达到要求:

1、编写控制器方法

@RequestMapping("/m2")
public String m2(Model model){
    model.addAttribute("name","大笨蛋");
    return "result";
}

2、编写敏感词拦截器

// 敏感词拦截器 public class SensitiveWordInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {        return true;   }    @Override

// 敏感词拦截器
public class SensitiveWordInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        return true;
   }
    @Override 
public void postHandle(HttpServletRequest request,HttpServletResponse response, Object
handler, ModelAndView modelAndView) {
        // 敏感词列表
        String[] sensitiveWords = {"坏人","暴力","笨蛋"};
        // 获取model中所有数据
        Map<String, Object> model = modelAndView.getModel();
        Set<Map.Entry<String, Object>> entries = model.entrySet();
        // 遍历model
        for (Map.Entry<String, Object> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue().toString();
            // 将model值和敏感词列表遍历比对
            for (String sensitiveWord : sensitiveWords) {
                // 如果model值包含敏感词,则替换
               if(value.contains(sensitiveWord)){
                    String newStr = value.replaceAll(sensitiveWord, "***");
                    model.put(key,newStr);
               }
           }
       }
   }
}

3、配置拦截器

<!-- 配置拦截器-->
<mvc:interceptors>
    <!-- 敏感词拦截器 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.itbaizhan.interceptor.SensitiveWordInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

SpringMVC跨域请求_同源策略 

 同源策略是浏览器的一个安全功能。同源,指的是两个URL的协 议,域名,端口相同。浏览器出于安全方面的考虑,不同源的客户 端脚本在没有明确授权的情况下,不能读写对方资源。

哪些不受同源策略限制:

 最容易收到同源策略影响的就是Ajax请求。

SpringMVC跨域请求_跨域请求 

 当请求URL的协议、域名、端口三者中任意一个与当前页面URL不 同时即为跨域。浏览器执行JavaScript脚本时,会检查当前请求是否 同源,如果不是同源资源,就不会被执行。

 比如:

1、编写控制器方法

@RequestMapping("/m3")
@ResponseBody
public String m3(){
    System.out.println("测试跨域请求");
    return "success";
}

2、编写JSP页面,发送异步请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>跨域请求</title>
        <script src="/js/jquery2.1.1.min.js"></script>
        <script>
            $(function (){
                $("#btn").click(function() {
                    //$.get("http://localhost:8080/m3",function(data) {
                    //    console.log(data);
                    // })
                  $.get("http://127.0.0.1:8080/m3",function(data) {
                        console.log(data);
                   })
               })
           })
        </script>
    </head>
    <body>
        <button id="btn">异步请求</button>
    </body>
</html>

 SpringMVC跨域请求_控制器接收跨域请求

SpringMVC提供了注解@CrossOrigin解决跨域问题。用法如下:

@RequestMapping("/m3")
@ResponseBody
// 如果请求从http://localhost:8080发出,则允许跨域访问
@CrossOrigin("http://localhost:8080")
public String m3(){
    System.out.println("测试跨域请求");
    return "success";
}

SSM整合_需求分析

接下来我们使用Maven+Spring+MyBatis+SpringMVC完成一个案 例,案例需求为在页面可以进行添加学生+查询所有学生!

案例需要使用以下技术:

1、使用Maven创建聚合工程,并使用Maven的tomcat插件运行工 程

2、使用Spring的IOC容器管理对象

3、使用MyBatis操作数据库

4、使用Spring的声明式事务进行事务管理

5、使用SpringMVC作为控制器封装Model并跳转到JSP页面展示数据

6、使用Junit测试方法

7、使用Log4j在控制台打印日志

案例的编写流程如下:

1、创建maven父工程,添加需要的依赖和插件

2、创建dao子工程,配置MyBatis操作数据库,配置Log4j在控制台 打印日志。

3、创建service子工程,配置Spring声明式事务

4、创建controller子工程,配置SpringMVC作为控制器,编写JSP页 面展示数据。

5、每个子工程都使用Spring进行IOC管理

# 准备数据库数据
CREATE DATABASE `student`;
USE `student`;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) DEFAULT NULL,
  `sex` VARCHAR(10) DEFAULT NULL,
  `address` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8;
INSERT  INTO `student`(`id`,`name`,`sex`,`address`)
VALUES (1,'程序员','男','北京'),(2,'辛苦学堂','女','北京');

 SSM整合_创建父工程

创建maven父工程,添加需要的依赖和插件

<properties>
    <!--Spring版本-->
  <spring.version>5.2.12.RELEASE</spring.version>
</properties>
<dependencies>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <!-- mysql驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
    <!-- druid连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.8</version>
    </dependency>
    <!-- MyBatis与Spring的整合包-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.6</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- springmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- 事务 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.7</version>
    </dependency>
    <!-- jstl -->
    <dependency>
        <groupId>org.apache.taglibs</groupId>
        <artifactId>taglibs-standard-spec</artifactId>
        <version>1.2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.taglibs</groupId>
        <artifactId>taglibs-standard-impl</artifactId>
        <version>1.2.5</version>
    </dependency>
    <!-- servlet -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <!-- jsp -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}
</version>
    </dependency>
    <!-- log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <!-- tomcat插件 -->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-mavenplugin</artifactId>
            <version>2.1</version>
            <configuration>
                <port>8080</port>
                <path>/</path>
                <uriEncoding>UTF8</uriEncoding>
                <server>tomcat7</server>
                <systemProperties>
                  <java.util.logging.SimpleFormatter.format>
                      %1$tH:%1$tM:%1$tS %2$s%n%4$s: %5$s%6$s%n
                  </java.util.logging.SimpleFormatter.format>
                </systemProperties>
            </configuration>
        </plugin>
   </plugins>
</build>

SSM整合_创建dao子工程

1、在父工程下创建maven普通java子工程

2、编写实体类

public class Student {
    private int id;
    private String name;
    private String sex;
    private String address;
    // 省略getter/setter/tostring/构造方法
}

3、编写持久层接口

@Repository
public interface StudentDao {
    // 查询所有学生
    @Select("select * from student")
    List<Student> findAll();
    
    // 添加学生
    @Insert("insert into student values(null,#{name},#{sex},#{address})")
    void add(Student student);
}

4、编写log4j.properties配置文件

log4j.rootCategory=debug, CONSOLE, LOGFILE
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%d{MM/dd HH:mm:ss}] %-6r [%15.15t]
%-5p %30.30c %x - %m\n

5、编写数据库配置文件druid.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///student
jdbc.username=root
jdbc.password01=root

6、编写MyBatis配置文件SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>

7、编写Spring配置文件applicationContext-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/beans
                          http://www.springframework.org/schema/beans/spring-beans.xsd
                          http://www.springframework.org/schema/context
                          http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 读取数据库配置文件 -->
    <context:property-placeholder location="classpath:druid.properties">
</context:property-placeholder>
    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <!-- SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:SqlMapConfig.xml">
</property>
    </bean>
    <!-- 配置扫描包对象,为包下的接口创建代理对象 -->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.itbaizhan.dao"></property>
    </bean>
</beans>

8、测试持久层接口的方法

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-dao.xml")
public class StudentDaoTest {
    @Autowired
    private StudentDao studentDao;
    @Test
    public void testFindAll(){
        List<Student> all = studentDao.findAll();
        all.forEach(System.out::println);
   }
    @Test
    public void testAdd(){
        Student student = new Student(0,"SXT", "女", "上海");
        studentDao.add(student);
   }
}

SSM整合_创建service子工程 

1、在父工程下创建maven普通java子工程

2、service子工程引入dao子工程的依赖

<dependencies>
    <dependency>
        <groupId>com.itbaizhan</groupId>
        <artifactId>ssm_dao</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

3、创建服务层方法

@Service
public class StudentService {
    @Autowired
    private StudentDao studentDao;
    public List<Student> findAllStudent(){
        return studentDao.findAll();
   }
    
    public void addStudent(Student student){
        studentDao.add(student);
   }
}

4、创建服务层的Spring配置文件applicationContextservice.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:aop="http://www.springframework.org/schema/aop"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- 包扫描 -->
    <context:component-scan basepackage="com.itbaizhan.service"></context:component-scan>
    <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 通知 -->
    <tx:advice id="txAdvice" transactionmanager="transactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- 切面 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itbaizhan.service.*.*(..))"></aop:advisor>
    </aop:config>
</beans>

SSM整合_创建controller子工程 

1、在父工程下使用maven创建web类型子工程

2、controller工程引入service子工程的依赖,并配置ssm父工程

<parent>
    <artifactId>ssm_demo</artifactId>
    <groupId>com.itbaizhan</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
    <dependency>
        <groupId>com.itbaizhan</groupId>
        <artifactId>ssm_service</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

3、编写控制器类

@Controller
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private StudentService studentService;
    @RequestMapping("/all")
    public String all(Model model){
        List<Student> allStudent = studentService.findAllStudent();
        model.addAttribute("students",allStudent);
        return "allStudent";
 }
    
    @RequestMapping("/add")
    public String add(Student student){
        studentService.addStudent(student);
        // 重定向到查询所有学生
        return "redirect:/student/all";
   }
}

4、编写SpringMVC配置文件springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:context="http://www.springframework.org/schema/context"
      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
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描Controller包 -->
    <context:component-scan basepackage="com.itbaizhan.controller"/>
    <!-- 配置视图解析器 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.vie
w.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 开启SpringMVC注解的支持 -->
    <mvc:annotation-driven/>
    <!-- 放行静态资源 -->
    <mvc:default-servlet-handler />
</beans>

5、编写Spring的总配置文件applicationContext.xml,该文件引入 dao和service层的Spring配置文件

<?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/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="applicationContextdao.xml"></import>
    <import resource="applicationContextservice.xml"></import>
</beans>

6、在web.xml中配置Spring监听器,该监听器会监听服务器启动, 并自动创建Spring的IOC容器

<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/javaee
        http://xmlns.jcp.org/xml/ns/javaee/webapp_3_1.xsd"
         version="3.1">
    <display-name>Archetype Created Web Application</display-name>
    <!-- 创建spring容器的监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
</web-app>

7、在web.xml中配置SpringMVC的前端控制器和编码过滤器

<!--前端控制器-->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
  <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<!--编码过滤器-->
<filter>
    <filter-name>encFilter</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>encFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

8、编写JSP页面allStudent.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <head>
        <title>所有学生</title>
    </head>
    <body>
       <%-- 添加学生表单 --%>
        <form action="/student/add" method="post">
           姓名:<input name="name">
           性别:<input name="sex">
           地址:<input name="address">
            <input type="submit" value="提交">
        </form>
       <%-- 展示学生表格 --%>
        <table width="500" cellpadding="0" cellspacing="0" border="1" align="center">
            <tr>
                <th>id</th>
                <th>姓名</th>
                <th>性别</th>
                <th>地址</th>
            </tr>
            <c:forEach items="${students}" var="student">
                <tr>
                    <td>${student.id}</td>
                    <td>${student.name}</td>
                    <td>${student.sex}</td>
                    <td>${student.address}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
</html>

SSM整合_运行项目 

1、在idea中配置使用tomcat插件启动maven父项目

 2、启动项目,访问http://localhost:8080/student/all

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/50321.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt报错总结

转载 Qt报错 widget.obj的问题 遇到这种情况可能是链接出错造成的&#xff0c;所以需要首选就是需要将生成的bulid文件进行删除&#xff0c;然后运行&#xff0c;基本可以了 补充知识&#xff1a; QtCreator中qmake、构建、运行、清理等区别与联系 qt执行流程&#xff1a;qma…

模式也能开盲盒,”盲返“模式带动电商平台共享经济

今年元月份&#xff0c;国务院也是提出消费返利、消费优惠、利润分享属于电商平台共享经济的促销模式&#xff0c;属于合法合规的新业态经济以及新零售重大变革的突破&#xff0c;全民参与共同富裕。 而最近市场上出了个很火的电商模式——消费盲返&#xff0c;是一个针对每个…

MacBook Pro 耗电严重的终极解决办法2022年

背景&#xff1a; 最近在用mac时发现一个问题&#xff0c;合上盖子之后&#xff0c;明天打开&#xff0c;没有插电源的情况下&#xff0c;就会没电&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;非常影响使用&#xff0c;最后才发现是…

第十一章:Java对象内存布局和对象头

对象内存布局对象头运行时元数据类型指针&#xff08;类元数据&#xff09;实例数据对齐填充对象内存布局之JOL 证明GC分代年龄说明压缩指针参数对象内存布局 兄弟们感兴趣的话&#xff0c;在 JVM 篇有对 对象的详细介绍&#xff1a;对象实例化内存布局 对象头 运行时元数据 …

datax-hdfsReader 学习

今天同事遇到了一个问题。 就是hdfsreader->mysqlwriter这种的时候。 有的分区没有数据会报错。 com.tencent.s2.dataingestion.common.exception.DataXException: Code:[HdfsReader-08], Description:[您尝试读取的文件目录为空.]. - 未能找到待读取的文件,请确认您的配…

持久层框架设计实现及MyBatis源码分析 ---- MyBatis基础回顾及高级应用

一、基本应用 基本开发步骤&#xff1a; ① 添加MyBatis的坐标 ② 创建xxx数据表 ③ 编写Xxx实体类 ④ 编写sql映射⽂件XxxMapper.xml ⑤ 编写核⼼配置⽂件SqlMapConfig.xml ⑥ 编写测试类 二、配置文件介绍 1. sql映射配置文件 XxxMapper.xml (1) 基础使用 (2) 动态SQL w…

卡尔曼滤波:The Scaler Kalman Filter常量卡尔曼滤波器

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 估计一个常数的通常做法是&#xff0c;做多次测量&#xff08;measurement)&#xff0c;然后使用测量的平均值作为估计值。从统计学的思想上来说&#xff0c;这种做法可以尽量减小估计的误差。这种方…

SpringBoot+Vue实现前后端分离的宠物医院管理系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…

Fiddler抓包工具是最强大最好用的 Web 调试工具之一

Fiddler是最强大最好用的Web调试工具之一&#xff0c;它能记录所有客户端和服务器的http和https请求&#xff0c;允许你监视&#xff0c;设置断点&#xff0c;甚至修改输入输出数据. 使用Fiddler无论对开发还是测试来说&#xff0c;都有很大的帮助。 目录 Fiddler的基本介绍 …

【C++11重点语法上】lambda表达式,初始化列表

目录 引子&#xff1a;C11为什么的源来 语法1&#xff1a;初始化列表 1.2.2 多个对象的列表初始化 语法3&#xff1a;默认成员函数控制&#xff08;delete&#xff0c;default&#xff09; 语法4&#xff1a;lambda表达式 引子&#xff1a;C11为什么的源来 在2003年C标准…

22年11月-外包-面试题

目录背景题目Spring怎么解决循环依赖&#xff1f;什么是循环依赖第一种&#xff1a;互相依赖第二种&#xff1a;三者间依赖第三种&#xff1a;自我依赖三级缓存补充&#xff1a;那第三级缓存的作用是什么&#xff1f;补充&#xff1a;Spring 中哪些情况下&#xff0c;不能解决循…

【Hadoop】在云服务器上部署Hadoop2.7.1伪分布式集群

文章目录一、准备Hadoop压缩包并安装1、安装Hadoop&#xff08;1&#xff09;准备好hadoop压缩包&#xff08;2&#xff09;安装hadoop&#xff08;3&#xff09;查看是否安装成功2、将hadoop添加到环境变量&#xff08;1&#xff09;在文件末尾添加以下内容&#xff08;2&…

怎样图片转文字?两分钟让你实现快速转文字

在日常的办公中&#xff0c;我们经常会遇到需要将纸质文件里的文字提取出来&#xff0c;再转换为电子档的情况&#xff0c;如果我们采用手动输入的话&#xff0c;不仅速度太慢&#xff0c;而且还可能因此耽误到后边的工作&#xff0c;是不是已经有小伙伴遇到这种现象&#xff0…

[附源码]Python计算机毕业设计Django房产中介管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

[附源码]计算机毕业设计springboot路政管理信息系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

RFC(Remote function call)

文章目录1 Definition2 Call process3. Communication4 Communication module5 RFC version .6 RFC and Web service7 Remote object maintain8 Call RFC1 Definition 2 Call process 3. Communication 4 Communication module 5 RFC version . 6 RFC and Web service 7 Remote…

mysql的主从复制

文章目录前言主备原理binlog的三种格式循环复制问题主备的搭建总结前言 mysql在日常中的使用是比较多的&#xff0c;大部分可能也都搭建过主从复制&#xff0c;或者集群模式。但是其中的原理不知道大家是否清楚。今天我们主要介绍的就是mysql主从复制的原理。 主备原理 主备…

Transformer对接公司需求的调研报告

1. 结构 从宏观的视角开始 首先将这个模型看成是一个黑箱操作。在机器翻译中&#xff0c;就是输入一种语言&#xff0c;输出另一种语言。 那么拆开这个黑箱&#xff0c;我们可以看到它是由编码组件、解码组件和它们之间的连接组成。 编码组件部分由一堆编码器&#xff08;enc…

Open vSwitch系列之数据结构解析深入分析ofpbuf

上一篇我们分析了hmap&#xff0c;hamp可以说是Open vSwitch中基石结构&#xff0c;很多Open vSwitch中数据结构都依赖hmap。本篇我们来分析一下ofpbuf&#xff0c;这个结构&#xff0c;我们从名字上就可得知&#xff0c;此数据结构用于存储数据的&#xff0c;比如收发OpenFlow…

1543_AURIX_TC275_CPU子系统_CPU内核实现特性

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 这个章节看的信息应该是针对内核设计实现上TC275的具体实现特点&#xff0c;应该是覆盖了很多内核中的实施相关的特性的。 1. 在上下文功能支持上&#xff0c;P和更灵活一些。E核只支持DSP…