SpringMVC学习笔记


一、知识回顾

1.回顾MVC

  • M:Model模型(dao,service),是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
  • V:View视图层(jsp),指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操作的方式。
  • C:Controller控制器(Servlet),指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。
    在这里插入图片描述

2.回顾Servlet

(1)导入依赖
创建一个普通的maven项目,删除src文件夹,在pom文件中导入以下依赖:

<!--  导入依赖 -->
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.9</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>

(2)创建子项目
添加框架支持
在这里插入图片描述
在这里插入图片描述
(3)编写Servlet类
在这里插入图片描述

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取前端参数
        String method = request.getParameter("method");
        if(method.equals("add")){
            request.getSession().setAttribute("msg","执行了add方法");
        }
        if(method.equals("delete")){
            request.getSession().setAttribute("msg","执行了delete方法");
        }
        //2.调用业务层
        //3.视图转发或者重定向
        request.getRequestDispatcher("index.jsp").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/hello" method="post">
    <label>
        <input type="text" name="method">
        <input type="submit">
    </label>
</form>

</body>
</html>

(4)测试
在这里插入图片描述
在这里插入图片描述

二、初识SpringMVC

1.SpringMVC工作原理

引用博客
在这里插入图片描述
工作流程:

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

2.常用组件总结

1、DispatcherServlet

是一种前端控制器,由框架提供。
作用:统一处理请求和响应。除此之外还是整个流程控制的中心,由 DispatcherServlet 来调用其他组件,处理用户的请求

2、HandlerMapping

处理器映射器,由框架提供。

作用:根据请求的 url、method 等信息来查找具体的 Handler(一般来讲是Controller)

3、Handler(一般来讲是Controller)

处理器,注意,这个需由工程师自己开发

作用:在 DispatcherServlet 的控制下,Handler对具体的用户请求进行处理

4、HandlerAdapter

处理器适配器 ,由框架提供。

作用:根据映射器找到的处理器 Handler 信息,按照特定的规则去执行相关的处理器 Handler。

5、ViewResolver

视图解析器,由框架提供。

作用: ViewResolver 负责将处理结果生成 View 视图。 ViewResolver 首先根据逻辑视图名解析成物理图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

6、View

视图,工程师自己开发

作用:View接口的职责就是接收model对象、Request对象、Response对象,并渲染输出结果给Response对象。

3.第一个SpringMVC(了解)

1、视图层代码hello.jsp

<%--
  Created by IntelliJ IDEA.
  User: wazou
  Date: 2022-05-12
  Time: 15:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

2、配置DispatchServlet web.xml

<!--1.注册DispatcherServlet-->
<servlet>
   <servlet-name>springmvc</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <!--DispatchServlet 要绑定Spring的配置文件(resources目录下的springmvc-servlet.xml)-->
   <init-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>classpath:springmvc-servlet.xml</param-value>
   </init-param>
   <!--启动级别-1-->
   <load-on-startup>1</load-on-startup>
</servlet>

<!--/ 匹配所有的请求;(不包括.jsp)-->
<!--/* 匹配所有的请求;(包括.jsp)-->
<servlet-mapping>
   <servlet-name>springmvc</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>

3、写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">
<!--    添加处理器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--    添加处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
   <!--前缀-->
   <property name="prefix" value="/WEB-INF/jsp/"/>
   <!--后缀-->
   <property name="suffix" value=".jsp"/>
</bean>


<!--Handler-->
<bean id="/hello" class="com.djq.controller.HelloController"/>
</beans>

4、实现controller

//注意:这里我们先导入Controller接口
public class HelloController implements Controller {

	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
	    //ModelAndView 模型和视图
	    ModelAndView mv = new ModelAndView();
	
	    //封装对象,放在ModelAndView中。Model
	    mv.addObject("msg","HelloSpringMVC!");
	    //封装要跳转的视图,放在ModelAndView中
	    mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
	    return mv;
	}

}

注册controller

<!--Handler-->
<bean id="/hello" class="com.djq.controller.HelloController"/>

5、测试
在这里插入图片描述

三、使用注解开发

1.简单使用

第一步,配置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">

   <!--1.注册servlet-->
   <servlet>
       <servlet-name>SpringMVC</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!-- 启动顺序,数字越小,启动越早 -->
       <load-on-startup>1</load-on-startup>
   </servlet>

   <!--所有请求都会被springmvc拦截 -->
   <servlet-mapping>
       <servlet-name>SpringMVC</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>

</web-app>

第二步,添加springmvc配置文件

<?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">

   <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
   <context:component-scan base-package="com.djq.controller"/>
   <!-- 让Spring MVC不处理静态资源 -->
   <mvc:default-servlet-handler />
   <!--
   支持mvc注解驱动
       在spring中一般采用@RequestMapping注解来完成映射关系
       要想使@RequestMapping注解生效
       必须向上下文中注册DefaultAnnotationHandlerMapping
       和一个AnnotationMethodHandlerAdapter实例
       这两个实例分别在类级别和方法级别处理。
       而annotation-driven配置帮助我们自动完成上述两个实例的注入。
    -->
   <mvc:annotation-driven />

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

</beans>

第三步,创建controller

@Controller
@RequestMapping("/HelloController")
public class HelloController {

   //真实访问地址 : 项目名/HelloController/hello
   @RequestMapping("/hello")
   public String sayHello(Model model){
       //向模型中添加属性msg与值,可以在JSP页面中取出并渲染
       model.addAttribute("msg","hello,SpringMVC");
       //web-inf/jsp/hello.jsp,return的结果即为视图的名字
       return "hello";
  }
}

测试:
在这里插入图片描述

使用springMVC必须配置的三大件:
处理器映射器、处理器适配器、视图解析器
通常,我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,而省去了大段的xml配置

2.Controller

控制器Controller

  • 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
  • 控制器负责解析用户的请求并将其转换为一个模型。
  • 在Spring MVC中一个控制器类可以包含多个方法
  • 在Spring MVC中,对于Controller的配置方式有很多种

接口实现controller:

  • 实现接口Controller定义控制器是较老的办法
  • 缺点是:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦;

注解实现controller:

  • @Controller注解类型用于声明Spring类的实例是一个控制器
  • Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器
    类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描。
<!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
<context:component-scan base-package="com.kuang.controller"/>
  • 增加一个ControllerTest2类,使用注解实现;
//@Controller注解的类会自动添加到Spring上下文中
@Controller
public class ControllerTest2{

   //映射访问路径
   @RequestMapping("/t2")
   public String index(Model model){
       //Spring MVC会自动实例化一个Model对象用于向视图中传值
       model.addAttribute("msg", "ControllerTest2");
       //返回视图位置
       return "test";
  }

}
  • 运行tomcat测试

注解是使用最多的方式!!

3.RequestMapping

@RequestMapping

  • @RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
  • 为了测试结论更加准确,我们可以加上一个项目名测试 myweb
  • 只注解在方法上面
@Controller
public class TestController {
   @RequestMapping("/h1")
   public String test(){
       return "test";
  }
}

访问路径:http://localhost:8080 / 项目名 / h1

  • 同时注解类与方法
@Controller
@RequestMapping("/admin")
public class TestController {
   @RequestMapping("/h1")
   public String test(){
       return "test";
  }
}

访问路径:http://localhost:8080 / 项目名/ admin /h1 , 需要先指定类的路径再指定方法的路径;

4.Restful风格

概念:
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

功能

资源:互联网所有的事物都可以被抽象为资源 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。 分别对应
添加、 删除、修改、查询。

传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get

http://127.0.0.1/item/queryItem.action?id=1 查询,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST

使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!

http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE

测试:
在Spring MVC中可以使用 @PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量上。

@Controller
public class RestFulController {

   //映射访问路径
   @RequestMapping("/commit/{p1}/{p2}")
   public String index(@PathVariable int p1, @PathVariable int p2, Model model){
       
       int result = p1+p2;
       //Spring MVC会自动实例化一个Model对象用于向视图中传值
       model.addAttribute("msg", "结果:"+result);
       //返回视图位置
       return "test";
       
  }
   
}

结果:
在这里插入图片描述

使用method属性指定请求类型

用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
测试:
增加一个方法

//映射访问路径,必须是POST请求
@RequestMapping(value = "/hello",method = {RequestMethod.POST})
public String index2(Model model){
   model.addAttribute("msg", "hello!");
   return "test";
}

我们使用浏览器地址栏进行访问默认是Get请求,会报错405:
在这里插入图片描述
如果将POST修改为GET则正常了;

//映射访问路径,必须是Get请求
@RequestMapping(value = "/hello",method = {RequestMethod.GET})
public String index2(Model model){
   model.addAttribute("msg", "hello!");
   return "test";
}

在这里插入图片描述

5.重定向和转发

原理

1、通过SpringMVC来实现转发和重定向 - 无需视图解析器;

测试前,需要将视图解析器注释掉

@Controller
public class ResultSpringMVC {
   @RequestMapping("/rsm/t1")
   public String test1(){
       //转发
       return "/index.jsp";
  }

   @RequestMapping("/rsm/t2")
   public String test2(){
       //转发二
       return "forward:/index.jsp";
  }

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

6.数据接受与处理

1、提交的域名称和处理方法的参数名一致

提交数据 : http://localhost:8080/hello?name=kuangshen

处理方法 :

@RequestMapping("/hello")
public String hello(String name){
   System.out.println(name);
   return "hello";
}

后台输出 : kuangshen

2、提交的域名称和处理方法的参数名不一致

提交数据 : http://localhost:8080/hello?username=kuangshen

处理方法 :

//@RequestParam("username") : username提交的域的名称 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){
   System.out.println(name);
   return "hello";
}

后台输出 : kuangshen
最好把@RequestParam都写上!

3、提交的是一个对象

要求提交的表单域和对象的属性名一致 , 参数使用对象即可

3.1、实体类

public class User {
   private int id;
   private String name;
   private int age;
   //构造
   //get/set
   //tostring()
}

3.2、提交数据 :
http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

3、处理方法 :

@RequestMapping("/user")
public String user(User user){
   System.out.println(user);
   return "hello";
}

后台输出 : User { id=1, name=‘kuangshen’, age=15 }

说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。

总结:

1.接收前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
2.假设传递的是一个对象,匹配对象中的字段名:如果名字一致则直接传递,否则为null(匹配不到)

7.数据传输到前端

1、第一种 : 通过ModelAndView

我们前面一直都是如此 . 就不过多解释

public class ControllerTest1 implements Controller {

   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","ControllerTest1");
       mv.setViewName("test");
       return mv;
  }
}

第二种 : 通过ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("name",name);
   System.out.println(name);
   return "hello";
}

第三种 : 通过Model

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("msg",name);
   System.out.println(name);
   return "test";
}

8.解决乱码问题

首先写一个表单form.jsp
注意要放在index.jsp的同级目录下,否则不能通过/form.jsp的方式访问

<%--
  Created by IntelliJ IDEA.
  User: wazou
  Date: 2022-05-14
  Time: 20:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/e/t" method="post">
    <label>
        <input type="text" name="name">
    </label>
    <input type="submit">
</form>
</body>
</html>

然后写一个Controller(EncodingController)

@Controller
public class EncodingController {
    @RequestMapping("/e/t")
    public String test1(@RequestParam("name")String name, Model model){
        model.addAttribute("msg",name);
        System.out.println(name);
        return "hello";
    }
}

访问from.jsp,提交中文内容
在这里插入图片描述
在这里插入图片描述
发现出现乱码!

解决方法:
在web.xml中添加过滤器

<!--      配置乱码过滤器  -->
<filter>
    <filter-name>encoding</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>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

再测试会发现结果正常!

在这里插入图片描述

四、JSON

1.什么是json

前后端分离: 后端提供接口,前端渲染后端的数据,通过json的形式传递

  • JSON,全称是 JavaScript Object Notation,即 JavaScript对象标记法。
  • JSON是一种轻量级(Light-Meight)、基于文本的(Text-Based)、可读的(Human-Readable)格式。
  • JSON 的名称中虽然带有JavaScript,但这是指其语法规则是参考JavaScript对象的,而不是指只能用于JavaScript 语言。
  • JSON无论对于人,还是对于机器来说,都是十分便于阅读和书写的,而且相比 XML(另一种常见的数据交换格式),文件更小,因此迅速成为网络上十分流行的交换格式。
  • 近年来JavaScript已经成为浏览器上事实上的标准语言,JavaScript 的风靡,与JSON 的流行也有密切的关系。
  • 因为JSON本身就是参考JavaScript 对象的规则定义的,其语法与JavaScript定义对象的语法几乎完全相同。
  • JSON格式的创始人声称此格式永远不升级,这就表示这种格式具有长时间的稳定性,10 年前写的文件,10年后也能用,没有任何兼容性问题。

json对象和js对象的互相转化:

//编写一个js对象
 let user = {
     name : "djq",
     age:3,
     sex:"男"
 }
 //将js对象转换为json对象
 let json = JSON.stringify(user);
 console.log(json)

 //将json对象转换为js对象
 let parse = JSON.parse(json);
 console.log(parse)

控制台输出:
在这里插入图片描述

2.Jackson的使用

1、导入jar包:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.2</version>
</dependency>

2、编写实体类(User)

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

3、使用Jackson处理json数据
首先解决乱码问题,在spring配置文件中加入以下代码:

<!--  统一解决乱码问题  -->
<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
public class UserController {

   @RequestMapping("/j1")
   @ResponseBody//不会走视图解析器,直接返回一个字符串或者使用@RestController,类下的所有方法都会不走视图解析器
   public String json1() throws JsonProcessingException {
       //创建一个jackson的对象映射器,用来解析数据
       ObjectMapper mapper = new ObjectMapper();
       //创建一个对象
       User user = new User("djq1",21,"男");
       //将我们的对象解析成为json格式
       String str = mapper.writeValueAsString(user);
       //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
       return str;
  }

}

结果:
在这里插入图片描述

- 处理列表数据

@Controller
public class UserController {

    @RequestMapping("/j1")
    @ResponseBody //不会走视图解析器,直接返回一个字符串或者使用@RestController,类下的所有方法都会不走视图解析器
    public String json1() throws JsonProcessingException {
        //jackson
        ObjectMapper mapper = new ObjectMapper();
        //创建一个对象
        User user = new User("djq1",21,"男");
        String str = mapper.writeValueAsString(user);
        return str;
    }

    @RequestMapping("/j2")
    @ResponseBody
    public String json2() throws JsonProcessingException {
        List<User> userList = new ArrayList<User>();
        //jackson
        ObjectMapper mapper = new ObjectMapper();
        //创建一个对象
        User user1 = new User("djq1",21,"男");
        User user2 = new User("djq2",21,"男");
        User user3 = new User("djq3",21,"男");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        String str = mapper.writeValueAsString(userList);
        return str;
    }
}

结果:
在这里插入图片描述

- 处理日期数据

@Controller
public class UserController {

    @RequestMapping("/j1")
    @ResponseBody //不会走视图解析器,直接返回一个字符串或者使用@RestController,类下的所有方法都会不走视图解析器
    public String json1() throws JsonProcessingException {
        //jackson
        ObjectMapper mapper = new ObjectMapper();
        //创建一个对象
        User user = new User("djq1",21,"男");
        String str = mapper.writeValueAsString(user);
        return str;
    }

    @RequestMapping("/j2")
    @ResponseBody
    public String json2() throws JsonProcessingException {
        List<User> userList = new ArrayList<User>();
        //jackson
        ObjectMapper mapper = new ObjectMapper();
        //创建一个对象
        User user1 = new User("djq1",21,"男");
        User user2 = new User("djq2",21,"男");
        User user3 = new User("djq3",21,"男");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        String str = mapper.writeValueAsString(userList);
        return str;
    }

    @RequestMapping("/j3")
    @ResponseBody
    public String json3() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();

        //方法一 自定义日期的格式 ,若使用原生java方式则直接返回dateFormat.format(date)
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //方法二:配置mapper
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        mapper.setDateFormat(dateFormat);

        Date date = new Date();

        return mapper.writeValueAsString(date);
    }
}

结果:
在这里插入图片描述
4、最后,对这些方法做一个封装:

public class JsonUtils {
    public static String getJson(Object object) throws JsonProcessingException {
        return getJson(object,"yyyy-MM-dd HH:mm:ss");
    }

    public static String getJson(Object object,String format) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        mapper.setDateFormat(dateFormat);

        return mapper.writeValueAsString(object);
    }
}

就可以直接使用JsonUtils.getJson方法来处理数据了。

3.Fastjson的使用

fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。实现json的转换方法很多,最后的实现结果都是一样的。

1、导入依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

2、测试

public class FastJsonDemo {
   public static void main(String[] args) {
       List<User> userList = new ArrayList<User>();

       User user1 = new User("djq1",21,"男");
       User user2 = new User("djq2",21,"男");
       User user3 = new User("djq3",21,"男");
       userList.add(user1);
       userList.add(user2);
       userList.add(user3);

       System.out.println("*******Java对象 转 JSON字符串*******");
       String str1 = JSON.toJSONString(list);
       System.out.println("JSON.toJSONString(list)==>"+str1);
       String str2 = JSON.toJSONString(user1);
       System.out.println("JSON.toJSONString(user1)==>"+str2);

       System.out.println("\n****** JSON字符串 转 Java对象*******");
       User jp_user1=JSON.parseObject(str2,User.class);
       System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);

       System.out.println("\n****** Java对象 转 JSON对象 ******");
       JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
       System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));

       System.out.println("\n****** JSON对象 转 Java对象 ******");
       User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
       System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);
  }
}

结果:
在这里插入图片描述

五、SSM整合

由于Springboot的整合要方便的多,所以这里不做笔记了,需要学习的可以去看狂神的视频:狂神SpringMVC教程

六、Ajax

1.Ajax简介

  • AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
  • AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
  • Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
  • 在 2005 年,Google 通过其 Google Suggest 使 AJAX 变得流行起来。Google Suggest能够自动帮你完成搜索单词。
  • Google Suggest 使用 AJAX 创造出动态性极强的 web 界面:当您在谷歌的搜索框输入关键字时,JavaScript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。就和国内百度的搜索框一样!
  • 传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网页。
  • 使用ajax技术的网页,通过在后台服务器进行少量的数据交换,就可以实现异步局部更新。
  • 使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。

2.axios使用

(占个坑,之后写一下axios的使用,就不写狂神视频里的jquery了)

七、拦截器

1.拦截器概述

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。

过滤器与拦截器的区别:拦截器是AOP思想的具体应用。

过滤器:

  • servlet规范中的一部分,任何java web工程都可以使用
  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器 :

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
  • 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

2.拦截器使用

1、编写一个拦截器

public class MyInterceptor implements HandlerInterceptor {

   //在请求处理的方法之前执行
   //如果返回true执行下一个拦截器
   //如果返回false就不执行下一个拦截器
   public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
       System.out.println("------------处理前------------");
       return true;
  }

   //在请求处理方法执行之后执行
   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
       System.out.println("------------处理后------------");
  }

   //在dispatcherServlet处理后执行,做清理工作.
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
       System.out.println("------------清理------------");
  }
}

2、在配置文件中配置拦截器

<!--关于拦截器的配置-->
<mvc:interceptors>
   <mvc:interceptor>
       <!--/** 包括路径及其子路径-->
       <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
       <!--/admin/** 拦截的是/admin/下的所有-->
       <mvc:mapping path="/**"/>
       <!--bean配置的就是拦截器-->
       <bean class="com.kuang.interceptor.MyInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

3、编写controller进行测试

//测试拦截器的控制器
@Controller
public class InterceptorController {

   @RequestMapping("/interceptor")
   @ResponseBody
   public String testFunction() {
       System.out.println("控制器中的方法执行了");
       return "hello";
  }
}

4、测试结果
在这里插入图片描述

3.拦截器应用(验证用户是否登录 )

实现思路
1、有一个登陆页面,需要写一个controller访问页面。
2、登陆页面有一提交表单的动作。需要在controller中处理。判断用户名密码是否正确。如果正确,向session中写入用户信息。返回登陆成功。
3、拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面。

1、编写一个登陆页面 login.jsp

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

<h1>登录页面</h1>
<hr>

<body>
<form action="${pageContext.request.contextPath}/user/login">
  用户名:<input type="text" name="username"> <br>
  密码:<input type="password" name="pwd"> <br>
   <input type="submit" value="提交">
</form>
</body>
</html>

2、编写一个Controller处理请求

@Controller
@RequestMapping("/user")
public class UserController {

   //跳转到登陆页面
   @RequestMapping("/jumplogin")
   public String jumpLogin() throws Exception {
       return "login";
  }

   //跳转到成功页面
   @RequestMapping("/jumpSuccess")
   public String jumpSuccess() throws Exception {
       return "success";
  }

   //登陆提交
   @RequestMapping("/login")
   public String login(HttpSession session, String username, String pwd) throws Exception {
       // 向session记录用户身份信息
       System.out.println("接收前端==="+username);
       session.setAttribute("user", username);
       return "success";
  }

   //退出登陆
   @RequestMapping("logout")
   public String logout(HttpSession session) throws Exception {
       // session 过期
       session.invalidate();
       return "login";
  }
}

3、编写一个登陆成功的页面 success.jsp

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

<h1>登录成功页面</h1>
<hr>

${user}
<a href="${pageContext.request.contextPath}/user/logout">注销</a>
</body>
</html>

4、在 index 页面上测试跳转!启动Tomcat 测试,未登录也可以进入主页!

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
 <head>
   <title>$Title$</title>
 </head>
 <body>
 <h1>首页</h1>
 <hr>
<%--登录--%>
 <a href="${pageContext.request.contextPath}/user/jumplogin">登录</a>
 <a href="${pageContext.request.contextPath}/user/jumpSuccess">成功页面</a>
 </body>
</html>

在这里插入图片描述
在这里插入图片描述

5、编写用户登录拦截器

public class LoginInterceptor implements HandlerInterceptor {

   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
       // 如果是登陆页面则放行
       System.out.println("uri: " + request.getRequestURI());
       if (request.getRequestURI().contains("login")) {
           return true;
      }

       HttpSession session = request.getSession();

       // 如果用户已登陆也放行
       if(session.getAttribute("user") != null) {
           return true;
      }

       // 用户没有登陆跳转到登陆页面
       request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
       return false;
  }

   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

  }
   
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

  }
}

6、在Springmvc的配置文件中注册拦截器

<!--关于拦截器的配置-->
<mvc:interceptors>
   <mvc:interceptor>
       <mvc:mapping path="/**"/>
       <bean id="loginInterceptor" class="com.kuang.interceptor.LoginInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

7、再次重启Tomcat测试!

OK,测试登录拦截功能无误.


版权声明:本文为qq_45733304原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。