springmvc

1.三层架构介绍

  • 表现层:WEB层,用来和客户端进行数据交互的。
  • 业务层:处理公司具体的业务逻辑的。
  • 持久层:用来操作数据库的。

2.mvc设计模式介绍

  • MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
  • Model:数据模型,JavaBean的类,用来进行数据封装。
  • View:指JSP、HTML用来展示数据给用户
  • Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等

3.Springmvc简介

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等。

4.请求流程

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
  5. 执行处理器(Controller,也叫后端控制器)。
  6. Controller执行完成返回ModelAndView
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
  11. DispatcherServlet响应用户

以上流程是以DispatcherServlet为核心轴,并且DispatcherServlet就是一个Servlet

5.XML方式

5.1创建项目并导包

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>

    <artifactId>demo</artifactId>

    <version>1.0-SNAPSHOT</version>

    <name>demo</name>

    <packaging>war</packaging>

    <properties>

        <maven.compiler.target>1.8</maven.compiler.target>

        <maven.compiler.source>1.8</maven.compiler.source>

        <junit.version>5.7.0</junit.version>

        <spring.version>5.2.5.RELEASE</spring.version>

    </properties>

    <dependencies>

        <dependency>

            <groupId>javax.servlet</groupId>

            <artifactId>javax.servlet-api</artifactId>

            <version>4.0.1</version>

            <scope>provided</scope>

        </dependency>

        <dependency>

            <groupId>org.junit.jupiter</groupId>

            <artifactId>junit-jupiter-api</artifactId>

            <version>${junit.version}</version>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>org.junit.jupiter</groupId>

            <artifactId>junit-jupiter-engine</artifactId>

            <version>${junit.version}</version>

            <scope>test</scope>

        </dependency>

        <!--Spring核心基础依赖-->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-core</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-beans</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-expression</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aop</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <!-- 增加了切面 -->

        <dependency>

            <groupId>org.aspectj</groupId>

            <artifactId>aspectjweaver</artifactId>

            <version>1.9.5</version>

        </dependency>

        <!-- spring jdbc -->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-jdbc</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <!--spring mvc-->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-webmvc</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-web</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <!--日志相关-->

        <dependency>

            <groupId>commons-logging</groupId>

            <artifactId>commons-logging</artifactId>

            <version>1.2</version>

        </dependency>

        <dependency>

            <groupId>log4j</groupId>

            <artifactId>log4j</artifactId>

            <version>1.2.17</version>

        </dependency>

        <!--测试相关-->

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.12</version>

            <scope>test</scope>

        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <version>1.18.12</version>

            <scope>provided</scope>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-databind</artifactId>

            <version>2.9.3</version>

        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-core</artifactId>

            <version>2.9.3</version>

        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-annotations</artifactId>

            <version>2.9.3</version>

        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>fastjson</artifactId>

            <version>1.2.47</version>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-war-plugin</artifactId>

                <version>3.3.0</version>

            </plugin>

        </plugins>

    </build>

</project>

5.2配置文件

5.2.1web.xml

 <?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xmlns="http://java.sun.com/xml/ns/javaee"

         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

         id="WebApp_ID" version="3.0">

    <display-name>SpringMVC_01_Basic</display-name>

    <welcome-file-list>

        <welcome-file>index.html</welcome-file>

        <welcome-file>index.htm</welcome-file>

        <welcome-file>index.jsp</welcome-file>

        <welcome-file>default.html</welcome-file>

        <welcome-file>default.htm</welcome-file>

        <welcome-file>default.jsp</welcome-file>

    </welcome-file-list>

    <servlet>

        <!-- 设置所有请求拦截到分发器

                         第一种 如果SpringMVC的配置文件,和web.xml在同一个目录

                         比如 MVC配置文件名字叫 basic-servlet.xml

                         只需要把servlet-name的值 设置为basic就可以,

                         但是 MVC配置文件的名字必须是xxx-servlet.xml的格式 -->

        <servlet-name>basic</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <!-- 指定配置文件-->

        <!-- <init-param> -->

        <!-- <param-name>contextConfigLocation</param-name> -->

        <!-- 可以放在任何地方 -->

        <!-- <param-value>/a/b/c/d/xxxxxxxxx.xml</param-value> -->

        <!-- 放在src下 -->

        <!-- <param-value>classpath:xxxxxxxxx.xml</param-value> -->

        <!-- </init-param> -->

         <!-- 项目启动就会加载这个servlet -->

                         <load-on-startup>1</load-on-startup>  

         </servlet>

    <servlet-mapping>

        <servlet-name>basic</servlet-name>

        <url-pattern>/</url-pattern>

        <!--

                         /* 会拦截jsp文件

                         / 不会拦截jsp

         -->

    </servlet-mapping>

</web-app>

5.2.2 basic-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:context="http://www.springframework.org/schema/context"

       xmlns:mvc="http://www.springframework.org/schema/mvc"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd

                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd

                  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">

    <!-- 使用XML进行映射

            MVC框架基本两个点

                              1 url怎么映射进去进行处理

                              2 处理完如何找到视图

    -->

    <!-- 处理映射器配置-->

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

    <!-- 创建映射,配置映射器,name必须是 / 打头-->

    <bean name="/w" class="com.tledu.controller.XmlMappingController"/>

    <!-- 视图解析器-->

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/WEB-INF/jsp/"/>

        <property name="suffix" value=".jsp"/>

    </bean>

</beans>

5.3控制器类

 

package com.tledu.controller;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class XmlMappingController extends AbstractController {

    @Override

    protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {

        System.out.println("Welcome~");

        return new ModelAndView("welcome");

    }

}

5.4jsp页面

 

视图解析器这里,我们指定了文件的目录和后缀

当controller返回了welcome的时候 就会去找WEB-INF/jsp/welcome.jsp

需要创建对应的jsp

6.注解方式

6.1配置文件

<?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/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd

                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd

                  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">

         <context:component-scan base-package="com.tledu.zrz.springmvc.controller"/>

         <mvc:annotation-driven />

         <!--视图解析器 -->

         <bean

                  class="org.springframework.web.servlet.view.InternalResourceViewResolver">

                  <property name="prefix"value="/WEB-INF/jsp/"/>

                  <property name="suffix"value=".jsp"/>

         </bean>

</beans>

 

  1. 配置包扫描,需要能把controller放到spring容器管理
  2. 添加一个Controller类,并加上Controller注解
  3. 类上加@RequestMapping(""),配置地址和controller的映射关系
  4. 在方法上加@RequestMapping(""),配置地址和方法的映射关系
  5. 执行方法,并返回一个字符串,这个字符串就是view-name

6.2常用注解

1.     @Controller

使用Controller注解之后,在方法上可以通过return的jsp或者html页面的名字,通过视图解析器,就能跳转到指定页面

如果没有Controller注解,这个类中的方法是不会被请求过去的

所对应的层也是controller层,表现层

2.     @RestController

RestController注解相当于Controller和ResponseBody一起使用

这个类中的方法可以被请求过来,但是方法中无法jsp和html页面,视图解析器就不会起到作用,返回的内容就是return后面的内容

3.     @RequestMapping

是Spring Web应用中最常用到的注解之一,这个注解会将http请求映射到MVC和Controller控制器的处理方法上

@GetMapping

@PostMapping

@PutMapping

@DeleteMapping

4.     @RequestBody

@RequestBody 主要用于接收前端通过 请求体 传递给后端的JSON字符串中的数据

GET方式无请求体,所以使用@RequestBody的时候不能使用GET方式,而应该使用POST形式

5.     @RequestParam

用于接收前端传递过来的url中的参数(key=value)的形式

主要用于接收前后端key不一致的时候,使用@RequestParm来指定获取

6.     @PathVaraible

@PathVaraible主要用于获取url请求中的动态参数的

@RequestMapping(“/delete/{id}”)

public String delete(@PathVaraible(“id”) int id){}

当RequestMapping中需要动态传递过来参数的时候,需要通过@PathVaraible来接收

7.     @ResponseBody

如果方法需要返回JSON或者XML或者自定义内容到页面中去,就需要再方法上加上ResponseBody,这个时候,返回的数据就会不被视图解析器所解析

8.     SessionAttributes注解

用于多次执行控制器方法间的参数,可以通过value指定存入属性的名字

package com.tledu.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.SessionAttributes;

import org.springframework.web.bind.support.SessionStatus;

@Controller

@RequestMapping(path="/hello")

@SessionAttributes(value= {"username","password","age"},types=

        {String.class,Integer.class})

public class HelloController {

    /**

     * 向session中存入值

     * @return

     */

    @RequestMapping(path="/save")

    public String save(Model model) {

        System.out.println("向session域中保存数据");

        model.addAttribute("username", "root");

        model.addAttribute("password", "123");

        model.addAttribute("age", 20);

        return "success";

    }

    /**

     * 从session中获取值

     * @return

     */

    @RequestMapping(path="/find")

    public String find(ModelMap modelMap) {

        String username = (String) modelMap.get("username");

        String password = (String) modelMap.get("password");

        Integer age = (Integer) modelMap.get("age");

        System.out.println(username + " : "+password +" : "+age);

        return "success";

    }

    /**

     * 清除值

     * @return

     */

    @RequestMapping(path="/delete")

    public String delete(SessionStatus status) {

        status.setComplete();

        return "success";

    }

}

6.3  控制器类和参数绑定

6.3.1RequestMapping详解

1. RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系

2. RequestMapping注解可以作用在方法和类上

  • 作用在类上:第一级的访问目录
  • 作用在方法上:第二级的访问目录
  • 细节:路径可以不编写 / 表示应用的根目录开始
  • 细节:${ pageContext.request.contextPath }也可以省略不写,但是路径上不能写 /

3.RequestMapping的属性

  • path 指定请求路径的url
  • value value属性和path属性是一样的
  • method 指定该方法的请求方式
  • GetMapping
  • DeleteMapping
  • PutMapping
  • PostMapping
  • params 指定限制请求参数的条件
  • headers 发送的请求中必须包含的请求头

6.3.2 参数绑定说明

6.3.2.1请求参数的绑定说明

1.1绑定机制

1. 表单提交的数据都是k=v格式的username=haha&password=123

2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的

3. 要求:提交表单的name和参数的名称是相同的

2.1支持的数据类型

1.基本数据类型和字符串类型

2. 实体类型(JavaBean)

3.集合数据类型(List、map集合等)

6.3.2.2基本数据类型和字符串类型

  • 提交表单的name和参数的名称是相同的
  • 区分大小写
  • 如果名称不相同可以通过@RequestParam("user"),指定参数名字
  • 如果参数是必传的@RequestParam(required = true

6.3.2.3实体类型(JavaBean)

  • 提交表单的name和JavaBean中的属性名称需要一致
  • 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:address.name

6.3.2.4给集合属性数据封装

  • 表单提提交
  • list:多个同名属性设置list
  • 获取通过json的方式进行提交
  • 需要设置注解@RequestBody

6.3.2.5请求参数中文乱码的解决

1. 在web.xml中配置Spring提供的过滤器类

<!-- 配置过滤器,解决中文乱码的问题 -->

<filter>

<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>

 <url-pattern>/*</url-pattern>

 </filter-mapping>

6.3.2.6 自定义类型转换器

1. 表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明Spring框架内部会默认进行数据类型转换。

2. 如果想自定义数据类型转换,可以实现Converter的接口

1.自定义类型转换器

package com.tledu.spring_mvc_basic.utils;

import org.springframework.core.convert.converter.Converter;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

public class StringToDateConverter implements Converter<String, Date> {

    @Override

    public Date convert(String source) {

        // 判断

        if(source == null) {

            throw new RuntimeException("参数不能为空");

        }

        try {

            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

// 解析字符串

            Date date = df.parse(source);

            return date;

        } catch (Exception e) {

            throw new RuntimeException("类型转换错误");

        }

    }

}

2.注册自定义类型转换器,在springmvc.xml配置文件中编写配置

<!-- 注册自定义类型转换器 -->

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">

<property name="converters">

<set>

<bean class="cn.itcast.utils.StringToDateConverter"/>

</set>

</property>

</bean>

<!-- 开启Spring对MVC注解的支持 -->

<mvc:annotation-driven conversion-service="conversionService"/>

 json里日期参数格式化可以使用@JsonFormat(pattern = "yyyy/MM/dd")注解进行配置

import

<import resource="classpath:applicationContext.xml" />

可以通过<import> 导入别的配置文件

重定向

返回"redirect:地址"。就可以重定向到指定地址

怎么给前端返回json数据

加入接口不希望跳转界面,希望返回一个json格式的数据,可以在这个接口上加@ResponseBody

如果我们希望一个Controller所有的方法都返回json格式的数据,这个时候可以使用@RestController代替@Controller

7.地址参数

在resful风格的接口中,会直接通过地址进行参数的传递,如,在进行详情查询的时候,我们需要传递参数id,这个时候id这个参数就可以放在地址中进行传递。

 @GetMapping("/detail/{id}/{name}")

    public String userDetailPage(@PathVariable Integer id, @PathVariable("name") String name) {

        System.out.println(id);

        System.out.println(name);

        return "user-detail";

    }

 

使用步骤:

  1. 定义参数
    1. 会在地址上通过{参数名}指定参数
  1. 获取参数
    1. 请求方法的参数中加上@PathVariable
  1. 传递参数,参数直接写在url里面
    1. /detail/id参数/name参数

8.设置SessionAttributes变量

在我们进行请求的过程中,可能需要在多个请求之间传递一些信息,这个时候就可以通过SessionAttributes传递数据,通过这种方式定义的数据,就可以在多个请求之间共享。

注意这个里面的参数和HttpSession中的参数是有所区别的,所以不能通过HttpSession的api来删除这个参数

package com.tledu.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.SessionAttributes;

import org.springframework.web.bind.support.SessionStatus;

@Controller

@RequestMapping(path="/hello")

@SessionAttributes(value= {"username","password","age"},types=

        {String.class,Integer.class})

public class HelloController {

    /**

     * 向session中存入值

     * @return

     */

    @RequestMapping(path="/save")

    public String save(Model model) {

        System.out.println("向session域中保存数据");

        model.addAttribute("username", "root");

        model.addAttribute("password", "123");

        model.addAttribute("age", 20);

        return "success";

    }

    /**

     * 从session中获取值

     * @return

     */

    @RequestMapping(path="/find")

    public String find(ModelMap modelMap) {

        String username = (String) modelMap.get("username");

        String password = (String) modelMap.get("password");

        Integer age = (Integer) modelMap.get("age");

        System.out.println(username + " : "+password +" : "+age);

        return "success";

    }

    /**

     * 清除值

     * @return

     */

    @RequestMapping(path="/delete")

    public String delete(SessionStatus status) {

        status.setComplete();

        return "success";

    }

}

 

作用

可以多个请求之间共享数据,作用域是session作用域

怎么用

@SessionAttributes注解声明有哪些数据需要放在SessionAttributes中

通过model.addAttribute进行添加

通过model.getAttribute获取

通过SessionStatus status中status.setComplete();进行清除

9.SSM项目的搭建

9.1引入依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tledu</groupId>

    <artifactId>student-manager</artifactId>

    <version>1.0-SNAPSHOT</version>

    <name>student-manager</name>

    <packaging>war</packaging>

    <properties>

        <maven.compiler.target>1.8</maven.compiler.target>

        <maven.compiler.source>1.8</maven.compiler.source>

        <junit.version>5.7.0</junit.version>

        <spring.version>5.2.5.RELEASE</spring.version>

    </properties>

    <dependencies>

        <dependency>

            <groupId>javax.servlet</groupId>

            <artifactId>javax.servlet-api</artifactId>

            <version>4.0.1</version>

            <scope>provided</scope>

        </dependency>

        <dependency>

            <groupId>org.junit.jupiter</groupId>

            <artifactId>junit-jupiter-api</artifactId>

            <version>${junit.version}</version>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>org.junit.jupiter</groupId>

            <artifactId>junit-jupiter-engine</artifactId>

            <version>${junit.version}</version>

            <scope>test</scope>

        </dependency>

        <!--Spring核心基础依赖-->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-core</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-beans</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-expression</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <!-- 增加了切面 -->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aop</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.aspectj</groupId>

            <artifactId>aspectjweaver</artifactId>

            <version>1.9.5</version>

        </dependency>

        <!-- spring jdbc -->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-jdbc</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <!--spring mvc-->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-webmvc</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-web</artifactId>

            <version>${spring.version}</version>

        </dependency>

        <!--mybatis相关-->

        <dependency>

            <groupId>org.mybatis</groupId>

            <artifactId>mybatis</artifactId>

            <version>3.4.5</version>

        </dependency>

        <!-- 与spring整合 -->

        <dependency>

            <groupId>org.mybatis</groupId>

            <artifactId>mybatis-spring</artifactId>

            <version>1.3.1</version>

        </dependency>

        <!-- 数据库驱动 -->

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>8.0.12</version>

        </dependency>

        <!-- 连接池 -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>druid</artifactId>

            <version>1.1.7</version>

        </dependency>

        <!--jstl, 标签库-->

        <dependency>

            <groupId>javax.servlet</groupId>

            <artifactId>jstl</artifactId>

            <version>1.1.2</version>

        </dependency>

        <!-- https://mvnrepository.com/artifact/taglibs/standard -->

        <dependency>

            <groupId>taglibs</groupId>

            <artifactId>standard</artifactId>

            <version>1.1.2</version>

        </dependency>

        <!--日志相关-->

        <dependency>

            <groupId>commons-logging</groupId>

            <artifactId>commons-logging</artifactId>

            <version>1.2</version>

        </dependency>

        <dependency>

            <groupId>log4j</groupId>

            <artifactId>log4j</artifactId>

            <version>1.2.17</version>

        </dependency>

        <!--测试相关-->

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.12</version>

            <scope>test</scope>

        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->

        <!--通过注解生成get和set方法-->

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <version>1.18.12</version>

            <scope>provided</scope>

        </dependency>

        <!--

            json解析的依赖

                在我们接口返回实体类的时候,需要用到

        -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-databind</artifactId>

            <version>2.9.3</version>

        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-core</artifactId>

            <version>2.9.3</version>

        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-annotations</artifactId>

            <version>2.9.3</version>

        </dependency>

        <!--alibaba提供的json工具,将对象和JSONObject相互转换-->

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>fastjson</artifactId>

            <version>1.2.47</version>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-war-plugin</artifactId>

                <version>3.3.0</version>

            </plugin>

        </plugins>

    </build>

</project>

9.2添加配置文件

添加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"

       xmlns:context="http://www.springframework.org/schema/context"

       xmlns:aop="http://www.springframework.org/schema/aop"

       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"

       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-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--配置扫描注解-->

    <context:annotation-config/>

    <!--告诉spring,要扫描com.tledu包下面的注解-->

    <context:component-scan base-package="com.tledu.student_manager"/>

    <!--加上aop的约束-->

    <aop:aspectj-autoproxy/>

    <!--使用注解的方式进行MVC映射 -->

    <mvc:annotation-driven/>

    <!-- 视图解析器-->

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/WEB-INF/jsp/"/>

        <property name="suffix" value=".jsp"/>

    </bean>

    <!--让spring去管理mybatis-->

    <!--需要把mybatis所需要的依赖,放到spring容器中-->

    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 2) 数据库连接池 -->

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

        <property name="driverClassName" value="${jdbc.driver}"/>

        <property name="url" value="${jdbc.url}"/>

        <property name="username" value="${jdbc.username}"/>

        <property name="password" value="${jdbc.password}"/>

        <!--最大连接数-->

        <property name="maxActive" value="${jdbc.max}"/>

        <!--初始空闲池的个数-->

        <property name="minIdle" value="${jdbc.min}"/>

    </bean>

    <!-- 3) 获取 SqlSessionFactory 工厂类-->

    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="dataSource"/>

        <property name="configLocation" value="classpath:mybatis-config.xml" />

    </bean>

    <!-- 4) 搜索有哪些 mapper 实现类,把mapper接口自动配置成 spring 中的 <bean>-->

    <bean id="scannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">

        <!-- name="basePackage":(起始)包名, 从这个包开始扫描-->

        <property name="basePackage" value="com.tledu.dao"/>

    </bean>

    <!-- 使使用注解配置的事务行为生效 -->

    <tx:annotation-driven transaction-manager="txManager"/><!-- 仍然需要一个PlatformTransactionManager -->

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <!-- (这个需要的对象是在其他地方定义的) -->

        <property name="dataSource" ref="dataSource"/>

    </bean>

</beans>

 添加jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/erp16?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8

jdbc.username=root

jdbc.password=root

jdbc.max=50

jdbc.min=10

 添加mybatis-config.xml

<?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.tledu.student_manager.model"/>

    </typeAliases>

    <mappers>

        <package name="com.tledu.student_manager.dao"/>

    </mappers>

</configuration>

 添加log4j.properties配置

### Log4j配置 ###

#定义log4j的输出级别和输出目的地(目的地可以自定义名称,和后面的对应)

#[ level ] , appenderName1 , appenderName2

log4j.rootLogger=DEBUG,console,file

#-----------------------------------#

#1 定义日志输出目的地为控制台

log4j.appender.console = org.apache.log4j.ConsoleAppender

log4j.appender.console.Target = System.out

log4j.appender.console.Threshold=DEBUG

####可以灵活地指定日志输出格式,下面一行是指定具体的格式 ###

#%c: 输出日志信息所属的类目,通常就是所在类的全名

#%m: 输出代码中指定的消息,产生的日志具体信息

#%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行

log4j.appender.console.layout = org.apache.log4j.PatternLayout

log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#-----------------------------------#

#2 文件大小到达指定尺寸的时候产生一个新的文件

log4j.appender.file = org.apache.log4j.RollingFileAppender

#日志文件输出目录

log4j.appender.file.File=log/info.log

#定义文件最大大小

log4j.appender.file.MaxFileSize=10mb

###输出日志信息###

#最低级别

log4j.appender.file.Threshold=ERROR

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#-----------------------------------#

#3 druid

log4j.logger.druid.sql=INFO

log4j.logger.druid.sql.DataSource=info

log4j.logger.druid.sql.Connection=info

log4j.logger.druid.sql.Statement=info

log4j.logger.druid.sql.ResultSet=info

#4 mybatis 显示SQL语句部分

log4j.logger.org.mybatis=DEBUG

#log4j.logger.cn.tibet.cas.dao=DEBUG

#log4j.logger.org.mybatis.common.jdbc.SimpleDataSource=DEBUG

#log4j.logger.org.mybatis.common.jdbc.ScriptRunner=DEBUG

#log4j.logger.org.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG

#log4j.logger.java.sql.Connection=DEBUG

log4j.logger.java.sql=DEBUG

log4j.logger.java.sql.Statement=DEBUG

log4j.logger.java.sql.ResultSet=DEBUG

log4j.logger.java.sql.PreparedStatement=DEBUG

 配置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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"

         version="4.0">

    <servlet>

        <servlet-name>basic</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <!--指定配置文件-->

        <init-param>

            <param-name>contextConfigLocation</param-name>

            <!--可以放在任何地方 -->

            <!--<param-value>/a/b/c/d/xxxxxxxxx.xml</param-value> -->

            <!--

                由于我们的配置文件在resource目录下,所以需要如下配置

             -->

            <param-value>classpath:applicationContext.xml</param-value>

        </init-param>

    </servlet>

    <!--把所有的请求交给了spring mvc进行处理-->

    <servlet-mapping>

        <servlet-name>basic</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>

 

</web-app>

9.3添加对应模块的内容

添加对应Controller层、service层、dao层代码,完成增删改查的接口

注意事项

  1. 关于相应的包扫描路径都需要进行修改
  2. 由于使用了mybatis,并且在java中添加了xml文件,所以需要在maven中进行配置,让maven可以编译到java中的xml文件
  3. 注意访问配置文件的时候需要加上classpath前缀,这样才能访问到。

9.4编写前端界面

9.5配置静态文件目录

在applicationContext.xml中配置<mvc:resources mapping="/resources/**" location="/resources/" />

10. 添加拦截器

创建鉴权拦截器

public class AuthInterceptor extends HandlerInterceptorAdapter {

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        // 获取请求需要执行的方法名

        String methodName = handlerMethod.getMethod().getName();

        // 判断当前请求是否和登录操作相关

        HttpSession session = request.getSession(true);

        User loginUser = (User) session.getAttribute("loginUser");

        if (loginUser == null) {

            response.sendRedirect(request.getContextPath() + "/");

            // 终止后续请求

            return false;

        }

        // 放行

        return super.preHandle(request, response, handler);

    }

}

在spring中配置拦截器

 <mvc:interceptors>

        <mvc:interceptor>

            <!-- 以下配置中,必须按顺序配置:mapping > exclude-mapping > bean  -->

            <!-- 1.mapping:拦截路径 , 可以有多个mapping节点 -->

            <mvc:mapping path="/**"/>

                  <mvc:mapping path="/user/**"/>

            <!-- 不再拦截路径中的请求,完全不受理 -->

            <!-- 2.exclude-mapping:白名单,可以配置多个 -->

            <mvc:exclude-mapping path="/user/login" />

            <!-- 3.bean:配置拦截器类,只配置class即可 -->

            <bean class="com.tledu.student_manager.interceptor.AuthInterceptor"/>

        </mvc:interceptor>

    </mvc:interceptors>

 

实现登录

  1. 添加了登录界面,在登录界面里进行了表单提交
    1. 对应提交到user/login地址
  1. 在后台实现登录功能
    1. dao层根据用户名查询出用户
    2. 判断用户是否存在,不存在抛出用户不存在异常
    3. 存在判断密码是否正确,不正确抛出密码错误的异常
    4. 登录成功,将用户写入session
    5. 跳转页面
  1. 添加拦截器
    1. 在拦截器里,判断用户是否存在,如果不存在就跳转到首页
    2. 存在就放行
  1. 配置拦截器
    1. 配置哪些地址需要经过这个拦截器
    2. 配置那些地址是不需要拦截的

地址重定向

return "redirect:/user/list";

可以放回redirect: 进行地址重定向

11.添加异常处理

在项目运行过程中,难免会出现异常情况,这个时候,如果直接给用户显示一堆报错信息,就不太好了,针对系统的异常,我们往往需要统一进行处理,并且给用户进行一个比较友善的返回,这个时候就需要,我们进行统一的异常处理。

public class LoginException extends Exception {

    public LoginException() {

    }

    public LoginException(String message) {

        super(message);

    }

}

添加局部异常处理

 @ExceptionHandler(value = {LoginException.class})

public String handlerException(LoginException e, HttpServletRequest request) {

        // 需要手动设置错误信息到页面

        request.setAttribute("e", e);

        return "error";

}

该方法会处理该Controller中的异常

添加全局异常处理

@ControllerAdvice

public class TestController {

    @ExceptionHandler(value = {LoginException.class})

    public String handlerException(LoginException e, HttpServletRequest request) {

        // 需要手动设置错误信息到页面

        request.setAttribute("e", "e");

        return "error";

    }

}

通过@ControllerAdvice这个注解可以对Controller进行增强,可以添加全局异常处理

根据不同的场景的,返回不同的内容

  @ExceptionHandler(value = {Exception.class})

    public ModelAndView error(Exception e, HttpServletRequest request, HttpServletResponse response) {

        if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {

            // ajax调用

            e.printStackTrace();

            String sOut = "";

            StackTraceElement[] trace = e.getStackTrace();

            for (StackTraceElement s : trace) {

                sOut += "\tat " + s + "\r\n";

            }

            AjaxResult<String> ajaxResult = new AjaxResult<String>(500,sOut);

            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(ajaxResult));

            return new ModelAndView(new MappingJackson2JsonView(),jsonObject);

        } else {

            Map<String,Object> map = new HashMap<>();

            map.put("error", e);

            // 网站访问

            return new ModelAndView("error",map);

        }

    }

12. 文件上传功能的实现

引入文件上传的maven依赖

            <dependency>

            <groupId>commons-fileupload</groupId>

            <artifactId>commons-fileupload</artifactId>

            <version>1.3.2</version>

        </dependency>

 添加文件上传配置文件

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

        <!--单位b-->

        <property name="maxUploadSize" value="5000000000"/>

    </bean>

 定义文件上传的接口

@PostMapping("/upload")

    public String upload(MultipartFile file, HttpServletRequest request) {

        if (file.isEmpty()) {

            // 为空就不搭理了

            return "error";

        }

        // 说明上传了

        // getRealPath 获取指定目录的绝对路径,比如 E:/xxx/xx/xx 找的是TomCat下的路径,不是工作空间

        // 重新编译后就消失了

        String realpath = request.getServletContext().getRealPath(

                "/resources/upload");

        // E:\SortWare\Work\apache-tomcat-7.0.93\webapps\SpringMVC_02_User\resources\

        // upload/

        // System.out.println(realpath);

        // getOriginalFilename 获取文件名和后缀名

        File destFile = new File(realpath + "/"

                + System.currentTimeMillis() + file.getOriginalFilename());

        // org.apache.commons.io.FileUtils

        try {

            // 第一个参数是文件源的流

            // 第二个参数是到哪去

            FileUtils

                    .copyInputStreamToFile(file.getInputStream(), destFile);

        } catch (IOException e) {

            e.printStackTrace();

        }

        return "success";

    }

 

流程:

  1. 引入依赖
  2. 配置文件上传bean
  3. 定义接口 
    1. MultipartFile 接收前端传过来的文件
    2. 知道文件放在什么位置
      1. request.getServletContext.getRealPath("/resources/image")
      2. 最终生成的文件
      3. 需要创建File
      4. 把流写到最终生成文件里
      5. 通过地址访问到这个图片

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>

<head>

    <title>用户维护</title>

    <script src="${pageContext.request.contextPath}/resources/js/jquery-1.7.2.js"></script>

</head>

<body>

<input id="file" type="file">

<button id="uploadBtn">上传</button>

<div id="imageBox">

</div>

<script>

    $("#uploadBtn").click(function () {

        console.log("文件上传");

        // 获取文件

        var files = $("#file").prop("files");

        if (files.length == 0) {

            alert("请选择文件");

            return;

        }

        var file = $("#file").prop("files")[0];

        // 进行文件上传的操作

        var formData = new FormData();

        formData.append("file", file);

        $.ajax({

            url: "${pageContext.request.contextPath}/user/upload/avatar",

            type: "POST",

            data: formData,

            // 告诉jQuery不要去设置Content-Type请求头

            contentType: false,

            // 告诉jQuery不要去处理发送的数据

            processData: false,

            success(res) {

                console.log(res);

                $("#imageBox").append(`

                    <div>

                        <img src="${pageContext.request.contextPath}` + res.data + `"/>

                    </div>`

                )

            }

        });

    });

</script>

</body>

</html>

 

tomcat地址映射

修改配置文件conf/server.xml

在Host下添加

<Context path="/upload" docBase="D:\upload"></Context>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值