- SpringMVC

  • 原理

![](../../../我的坚果云/基于Java/Java学习路线/阶段4 Java开发框架/assert/SpringMVC1.JPG)

  • 开发步骤
    1. 导入SpringMVC相关坐标
    2. 配置SpringMV核心控制器·DispatherSerclet
    3. 创建Controller类和视图页面
    4. 使用注解配置Controller类中业务方法的映射地址
    5. 配置SpringMVC核心文件spring-mvc.xml

- web.xml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value><!--spring-mvc的配置映射-->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!--配置乱码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
</web-app>

- spring-mvc配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?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.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描1. controller包-->
<context:component-scan base-package="com.controller"/>
<mvc:default-servlet-handler/>

<!--2. 配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--2.1 页面前缀-->
<property name="prefix" value="/"/>
<!--2.2 页面后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--3. 开启mvc注解驱动-->
<mvc:annotation-driven/>
</beans>

<!--Json乱码问题解决-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

- 注解说明

注解 说明
@Controller 使用在web层实例化Bean
@RequestMapping 用于映射url到控制器类或一个特定的处理方法程序,可用于方法上;在类上表示所有响应请求的方法都是以该地址作为父路径
@RequestParam(“username”) 限定前端参数的name为username
@ResponseBody 不会走视图解析器,会直接返回字符串,作用在方法上搭配@Controller使用
@RestController 作用在类上,不走视图解析器,可代替@ResponseBody使用,其所作用的类下所有方法都只会返回字符串

- 重定向和转发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.controller;

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

@Controller
public class list {
@RequestMapping("/start")
public String tes(){
//转发方式一:‘/’+index.jsp
return "/index.jsp";
}

@RequestMapping("/start")
public String tes(){
//转发方式二:forword:/index.jsp
return "forword:/index.jsp";
}

@RequestMapping("/start")
public String tes(){
//重定向:redirect:/index.jsp
return "redirect:/index.jsp";
}
}

- 接受请求参数和数据回显

  • usercontroller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Controller
@RequestMapping("/user")
public class userController {

//localhost:8080/user/t1? name=xxx
@GetMapping("/t1")
public String test1(user u, Model model){
//1.前端接受参数
System.out.println("接收参数为"+u.toString());
//2.将返回的结果传递给前端。Model
model.addAttribute("msg",u);
//3.视图跳转
return "index";
}
}
  • index.jsp
1
2
3
4
5
6
7
8
9
10
11
12
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success!${msg["name"]}</h1>
<h1>Success!${msg["address"]}</h1>
<h1>Success!${msg["age"]}</h1>

</body>
</html>

- JSON

导入json

乱码解决(在spring-mvc中导入)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--Json乱码问题解决-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

Jackson使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Controller
public class JsonController {

@ResponseBody
@RequestMapping("/j1")
public String Json1() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
User user1 = new User("法外狂徒", "联盟峡谷", 20);
return mapper.writeValueAsString(user1);
//返回对象
}
@ResponseBody
@RequestMapping("/j2")
public String Json2() throws JsonProcessingException {
ObjectMapper mapper1 = new ObjectMapper();
List<User> userList=new ArrayList<User>();
userList.add(new User("赵信","峡谷草丛",18));
userList.add(new User("赵信","峡谷草丛",18));
userList.add(new User("赵信","峡谷草丛",18));
return mapper1.writeValueAsString(userList);
//返回对象数组
}

@ResponseBody
@RequestMapping("/j3")
public String Json3() throws JsonProcessingException {
ObjectMapper mapper1 = new ObjectMapper();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mapper1.writeValueAsString(sdf.format(new Date()));
//返回时间序列
}
}

- 拦截器配置

自定义配置

  1. web.xml中配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <!--前端控制器-->
    <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>
    </servlet>

    <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <!--只不匹配jsp-->
    <url-pattern>/</url-pattern>
    </servlet-mapping>

    </web-app>
  2. Springmvc.xml中配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <?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.xsd
    http://www.springframework.org/schema/context
    https://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <context:component-scan base-package="cn.justweb"/>
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"></property>
    <property name="suffix" value=".jsp"></property>
    </bean>

    <!--注解驱动,自动注入mvc里面的组件-->
    <mvc:annotation-driven/>

    <!--自定义拦截器的配置-->

    <!--先配谁先执行谁-->
    <mvc:interceptors>

    <!--配置对哪些资源进行拦截操作-->
    <mvc:mapping path="/**"/>

    <!--配置对哪些资源排除拦截操作,例如登陆和注册-->
    <mvc:exclude-mapping path="/user/login"/>
    <mvc:exculde-mapping path="/user/regist"/>
    <!--拦截器类-->
    <bean class="cn.justweb.interceptor.FirstInterceptor"></bean>
    <bean class="cn.justweb.interceptor.SecInterceptor"/>

    </mvc:interceptors>
    </beans>
  3. 定义一个拦截器FirstInterceptor,实现HandlerInterceptor接口,并重写其中的三个方法

  4. 第一个拦截器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    //配置的第一个拦截器
    public class FirstInterceptor implements HandlerInterceptor {
    /**
    * 执行流程:
    * 拦截器的preHandle方法执行了
    * controller中的testInterceptor方法
    * 拦截器postHandle方法执行了
    * 拦截器的afterCompletion执行了
    * */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("拦截器的preHandle方法执行了");
    //此处为true的时候才执行下面的事情
    return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("拦截器postHandle方法执行了");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("拦截器的afterCompletion执行了");
    }
    }
  5. 第二个拦截器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    //配置的第二个拦截器
    public class SecInterceptor implements HandlerInterceptor {
    /**
    * 执行流程:
    * 拦截器的preHandle方法执行了
    * 拦截器2的preHandle方法执行了
    * controller中的testInterceptor方法
    * 拦截器2的postHandle方法执行了
    * 拦截器postHandle方法执行了
    * 拦截器2的afterCompletion方法执行了
    * 拦截器的afterCompletion执行了
    * */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("拦截器2的preHandle方法执行了");
    return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("拦截器2的postHandle方法执行了");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("拦截器2的afterCompletion方法执行了");

    }
    }
  6. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    @Controller
    public class SpringMVCHandler {
    @RequestMapping("/testInterceptor")//拦截器
    public String testInterceptor(){
    System.out.println("controller中的testInterceptor方法");
    return "success";
    }
    }

- 异常处理

* 处理异常的两种处理方式

  1. 简单异常处理器(在springmvc.xml中配置)

  2. 自定义异常处理类( 实现HandlerExceptionResolver 接口)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!--默认错误视图-->
    <property name="defaultErrorView" value="error"></property>

    <property name="exceptionMappings">
    <map>
    <entry key="也可以是自定义异常类" value="错误视图"></entry>
    <entry key="java.lang.ClassCastException" value="error"></entry>
    </map>
    </property>
    </bean>
  3. 使用@ExceptionHandler注解实现异常处理(在controller中使用)。

    1
    2
    3
    4
    5
    6
    7
    @ExceptionHandler({自定义异常处理类.class})
    public String exception(MyException e){
    System.out.printrl(e.getMessage());
    e.printStackTrance();
    return "exception";
    }