SpringMVC学习笔记

SpringMVC

1.MVC架构

  • MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范
  • 是将业务逻辑、数据、显示分离的方法来写代码
  • MVC主要作用是:降低了视图和业务逻辑之间的双向耦合
  • MVC是一个架构模型,不是一种设计模式。

1.model(模型)

数据模型,提供要展示的数据,因此包括数据和业务。

  • 业务逻辑
  • 保存数据的状态

2.view(视图)

负责进行模型的展示,一般就是界面,客户可以看到的东西

职责:

  • 展示数据

3.controller(控制器)

接收用户的请求,委托给模型进行处理(状态改变),处理完之后再把返回的模型数据返回给视图,由视图负责展示。控制器相当于一个调度员。

职责:

  • 取得表单的数据
  • 调用业务逻辑
  • 转向指定页面

最经典的MVC就是:servlet+jsp+javabean的模式

分为model1时代和model2时代:

model1:早期开发使用的是model1 只有视图层跟模型层,jsp职责不单一

model2:分为视图层,模型层,控制层

4.MVC架构需要做的事情

  • 将url映射到java类或java类的方法
  • 封装用户提交的数据
  • 处理请求–>调用相关的业务处理—>封装响应数据
  • 将响应的数据进行渲染,.jsp/html等表示层数据

2.什么是SpringMVC

Spring MVC是Spring Framework 的一部分 ,是基于Java实现MVC的轻量级Web框架

官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html

1.SpringMVC的优点:

  • 轻量级,简单易学
  • 高效,基于请响应的mvc框架
  • 与spring兼容性好
  • 约定优于配置
  • 功能强大:restful 、数据验证、格式化、本地化、主题等
  • 简洁灵活

2.SpringMVC的设计思想:

Spring的web框架是围绕DispatcherServlet【调度Servlet】设计。

DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始使用Java 5以上的版本的用户可以采用基于注解形式进行开发。

3.中心控制器

Spring的web框架是围绕DispatcherServlet【调度Servlet】设计。

DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始使用Java 5以上的版本的用户可以采用基于注解形式进行开发。

SpringMVC框架像许多的其他mvc框架一样,以请求为驱动,围绕一个中心Servlet分派请求及提供其他功能,

DispatcherServlet是一个实际的Servlet

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAVRHy7b-1616511435139)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201223165929873.png)]

SpringMVC原理:

当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用 模型与视图渲染视图结果,将结果返回给中心控制器,在将结果返回给请求者。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QeEYrYAI-1616511435143)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201223171627039.png)]

3.SpringMVC的执行原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9S8ziqqL-1616511435144)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201223181703058.png)]

图为一个较为完整的SpringMVC流程图,实现表示SpringMVC框架提供的技术,不需要开发者实现,许仙表示需要开发者实现

简要的分析一下执行流程:

1.DispatcherServlet是一个前置控制器,是整个SpringMVC的控制中心。用户发送请求,DispatcherServlet接收并且拦截。

假设请求的url为:http://localhost:8080/SpringMVC/hello

将url拆分为三部分:

  • 服务器域名 http://localhost:8080
  • 部署在服务器的web站点 SpringMVC
  • 控制器 hello

分析url可知:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器去

2.HandlerMapping为处理器映射,DispatcherServlet调用HandlerMapping,HandlerMapping根据url查找Handler

3.HandlerExecution表示具体的Handler,主要的工作是根据url查找控制器。如以上的url被查找的控制器为hello。

4.HandlerExecution将解析后的信息传递给DispatcherServlet

5.HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler

6.Handler让具体的Controller执行

7.Controller将具体的执行信息返回给HandlerAdapter 如ModelAndView

8.HandlerAdapter 将视图模型或者逻辑名传递给DispatcherServlet

9.DispatcherServlet调用视图解析器来解析HandlerAdapter传递的逻辑试图名

10.视图解析器将解析的逻辑视图名传给DispatcherServlet

11.DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图

12.最终将试图传递给用户

4.helloSpringMVC

实现步骤:

  1. 新建一个web项目
  2. 导入相关的jar包
  3. 编写web.xml注册DispatcherServlet
  4. 编写Springmvc配置文件:处理器映射器、适配器
  5. 创建对应的控制类Controller
  6. 完成前端视图跟controller之间的对应
  7. 启动测试运行

使用SpringMVC必须配置的三大件:

处理器映射器、处理器适配器、视图解析器

通常只需手动配置视图解析器,其他两个只需要注解就可以实现。

1.配置版

1.新建一个web项目

2.导入相关依赖

   <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2.1-b03</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.2</version>
        </dependency>

3.配置web.xml 注册DispatcherServlet

<?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">
    <!--注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--绑定spring配置-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--设置启动等级-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4.创建springmvc配置文件:springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

5.配置处理器映射器

    <!--添加处理映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

6.配置处理器适配器

    <!--添加处理适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

7.配置视图解析器

   <!--添加视图解析器-->
    <!--视图解析器: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>

8.编写controller实现Controller接口

package com.mahui.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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;
    }
}

9.将自己的类交给SpringIOC容器注册bean

<!--注册controller-->
    <bean id="/hello" class="com.mahui.controller.HelloController"/>

10.编写前端交互页面

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

11.配置tomcat运行测试。

2.注解版

1.新建一个web

2.由于maven有资源过滤问题,所以将配置完善

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

3.导入相关依赖

      <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2.1-b03</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.2</version>
        </dependency>

4.配置web.xml 注册DispatcherServlet

<?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">
    <!--注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--绑定spring配置-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--设置启动等级-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

5.添加springmvc-servlet.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns: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="com.mahui.controller"/>
    <!--让spring不去处理静态的资源-->
    <mvc:default-servlet-handler/>
    <!--开启注解支持-->
    <mvc:annotation-driven/>
    <!--注册视图解析-->
    <bean id="InternalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>


</beans>

6.创建controller

package com.mahui.controller;

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

@Controller
public class MyController {

//访问的地址  http://localhost:8080/h1
    @RequestMapping("/h1")
    public String test(Model model){

        //业务处理像模型中添加msg可以在页面中取出并且渲染
        model.addAttribute("msg","hello spring mvc annotation");

        //试图跳转 /WEB-INF/jsp/hello.jsp
        return "hello";
    }
}

7.创建页面

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

8.配置tomcat启动测试

3.遇到的问题

遇到404页面,排查的步骤:

  1. 查看控制台输出,看一下是否缺少什么jar

  2. 如果jar包存在,显示无法输出,在idea项目发布中,添加lib目录,导入依赖

    在这里插入图片描述

  3. 重新启动tomcat测试

5.RestFul风格

1.什么是RestFul?

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

资源:互联网所有的事物都可以被抽象为资源

学习测试:

在springmvc中可以使用@PathVariable 注解,让方法参数的值对应绑定到一个URL模板变量上

    //http://localhost:8080/t2?a=1&b=2   传统的
    //http://localhost:8080/t2/1/3    RestFul风格
    @RequestMapping("/t2/{a}/{b}")
    public String test02( @PathVariable int a, @PathVariable int b, Model model){
        int  msg= a+b;
        model.addAttribute("msg",msg);
        return "hello";
    }

优点:

  • 使路径变得更加简洁
  • 获取参数更加方便,框架会自动进行类型转换
  • 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法。

使用method属性指定请求类型

用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型为GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE,TRACE等

测试:

    @RequestMapping(value = "/t2/{a}/{b}",method = RequestMethod.POST)
    public String test02( @PathVariable int a, @PathVariable int b, Model model){
        int  msg= a+b;
        model.addAttribute("msg",msg);
        return "hello";
    }

在这里插入图片描述

浏览器地址栏进行访问默认是GET请求,会报错405

将post修改为get即可

    //http://localhost:8080/t2/1/3    RestFul风格
    @RequestMapping(value = "/t2/{a}/{b}",method = RequestMethod.GET)
    public String test02( @PathVariable int a, @PathVariable int b, Model model){
        int  msg= a+b;
        model.addAttribute("msg",msg);
        return "hello";
    }

不同的请求方式对应的注解:

    @GetMapping
    @PostMapping
    @DeleteMapping
    @PutMapping
    @PatchMapping
//简化了@RequestMapping(value = "/t2/{a}/{b}",method = RequestMethod.GET)

6.重定向与转发

1.ModelAndView

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

springmvc-servlet.xml

  <!--注册ModelAndViewController-->
    <bean id="/test" class="com.mahui.controller.ModelAndViewController"/>

测试路径:http://localhost:8080/test

2.servletApi

通过设置ServletAPI,不需要视图解析器。将视图解析器注掉

  1. 通过HttpServletResponse进行输出
  2. 通过HttpServletResponse实现重定向
  3. 通过HttpServletRequest实现转发

@Controller
public class ServletAPIController {
    @RequestMapping("/result/t1")
    public void  test1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().write("通过HttpServletResponse进行输出");
    }
    @RequestMapping("/result/t2")
    public void  test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
      response.sendRedirect("/index.jsp");
    }
    @RequestMapping("/result/t3")
    public void  test3(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        request.setAttribute("msg","通过HttpServletRequest实现转发");
        request.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(request,response);
    }
}

3.SpringMVC

通过SpringMVC实现试图转发和重定向,同样也不需要视图转发

测试前将视图解析器注掉


@Controller
public class SpringMVCController {
    @RequestMapping("/smv/t1")
    public String test1(){
        //转发方式一
        return "/spring01.jsp";
    }

    @RequestMapping("/smv/t2")
    public String test2(){
        //转发方式二
        return "forward:/spring02.jsp";
    }

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

7.接收请求参数及数据回显

1.处理提交数据

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

提交的数据:http://localhost:8080/hello1?name=zhangsan

    @RequestMapping("/hello1")
    public String test1(String name){
        //http://localhost:8080/hello1?name=zhangsan
        System.out.println(name);
        return "hello";
    }
2.提交的域名和处理方法的参数名不一致

提交的数据:http://localhost:8080/hello2?username=zhangsan

需要使用注解:@RequestParam(“username”)

@RequestMapping("/hello2")
public String test2(@RequestParam("username") String name){
    //http://localhost:8080/hello2?username=zhangsan
    System.out.println(name);
    return "hello";
}

2.数据显示到前端

1.通过ModelAndView
public class ModelAndViewController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv = new ModelAndView();
        //返回一个模型视图对象
        mv.addObject("msg","ModelAndViewController");
        mv.setViewName("test");
        return mv;
    }
}
2.通过ModelMap
@Controller
public class MyController03 {
    @RequestMapping("hello/test1")
    public String test1(ModelMap modelMap){
        //封装要显示的数据
        modelMap.addAttribute("msg","ModelMap");
       return "hello";
    }
3.通过Model

    @RequestMapping("hello/test2")
    public String test2(Model model){
        //封装要显示的数据
        model.addAttribute("msg","Model");
        return "hello";
    }
3.提交的是一个对象

提交的数据:http://localhost:8080/hello3?id=1&name=zhangsan&age=66

实体类:

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

测试:

    @RequestMapping("/hello3")
    public String test3(User user){
        //http://localhost:8080/hello3?id=1&name=zhangsan&age=66
        System.out.println(user);
        return "hello";
    }

注意的是:如果使用对象,前端传来的参数名和对象名必须一致,否则就是null

8.乱码解决问题

前端表单:

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

测试:

@Controller
public class MyController04 {
    @RequestMapping("/e/t1")
    public String test1(HttpServletRequest request, HttpServletResponse response, Model model){
        //接收前端参数
        String name = request.getParameter("name");
        System.out.println(name);
        //返回前端参数
        model.addAttribute("msg",name);
        return "hello";
    }
}

测试结果:

网页乱码:

在这里插入图片描述

控制台乱码:

在这里插入图片描述

1.使用SpringMVC过滤器

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>

2.自己写过滤器

public class CharacterEncodingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    public void destroy() {

    }
}

web中配置


    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.mahui.Filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

3.使用大神写的

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
* 解决get和post请求 全部乱码的过滤器
*/
public class GenericEncodingFilter implements Filter {

   @Override
   public void destroy() {
  }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       //处理response的字符编码
       HttpServletResponse myResponse=(HttpServletResponse) response;
       myResponse.setContentType("text/html;charset=UTF-8");

       // 转型为与协议相关对象
       HttpServletRequest httpServletRequest = (HttpServletRequest) request;
       // 对request包装增强
       HttpServletRequest myrequest = new MyRequest(httpServletRequest);
       chain.doFilter(myrequest, response);
  }

   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
  }

}

//自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {

   private HttpServletRequest request;
   //是否编码的标记
   private boolean hasEncode;
   //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
   public MyRequest(HttpServletRequest request) {
       super(request);// super必须写
       this.request = request;
  }

   // 对需要增强方法 进行覆盖
   @Override
   public Map getParameterMap() {
       // 先获得请求方式
       String method = request.getMethod();
       if (method.equalsIgnoreCase("post")) {
           // post请求
           try {
               // 处理post乱码
               request.setCharacterEncoding("utf-8");
               return request.getParameterMap();
          } catch (UnsupportedEncodingException e) {
               e.printStackTrace();
          }
      } else if (method.equalsIgnoreCase("get")) {
           // get请求
           Map<String, String[]> parameterMap = request.getParameterMap();
           if (!hasEncode) { // 确保get手动编码逻辑只运行一次
               for (String parameterName : parameterMap.keySet()) {
                   String[] values = parameterMap.get(parameterName);
                   if (values != null) {
                       for (int i = 0; i < values.length; i++) {
                           try {
                               // 处理get乱码
                               values[i] = new String(values[i]
                                      .getBytes("ISO-8859-1"), "utf-8");
                          } catch (UnsupportedEncodingException e) {
                               e.printStackTrace();
                          }
                      }
                  }
              }
               hasEncode = true;
          }
           return parameterMap;
      }
       return super.getParameterMap();
  }

   //取一个值
   @Override
   public String getParameter(String name) {
       Map<String, String[]> parameterMap = getParameterMap();
       String[] values = parameterMap.get(name);
       if (values == null) {
           return null;
      }
       return values[0]; // 取回参数的第一个值
  }

   //取所有值
   @Override
   public String[] getParameterValues(String name) {
       Map<String, String[]> parameterMap = getParameterMap();
       String[] values = parameterMap.get(name);
       return values;
  }
}

在web.xml中进行配置

    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.mahui.Filter.GenericEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

4修改Tomcat的配置文件

<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
          connectionTimeout="20000"
          redirectPort="8443" />

5./和/*的区别

  • / 请求的不包括jsp文件
  • /*请求包括所有的包括jsp文件

9.JSON

1.什么是json

  • JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式
  • 采用完全独立于编程语言的文本格式来存储和表示数据
  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率

js对象格式:

{name: "张三", age: 18, sex: "男"}

json字符串格式:

{"name":"张三","age":18,"sex":"男"}

将js对象转换为json字符串使用JSON.stringify()方法

 //将对象转为json字符串
  var objectjson=JSON.stringify({a:"Hello",b:"Json"});

将json字符串转换为js对象使用JSON.parse()方法

  //将json字符串转换为对象
  var jsonobject=JSON.parse('{"a":"Hello","b":"Json"}');

测试:

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2020/12/25 0025
  Time: 9:42
  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>
<script type="text/javascript">

  var user={
      name:"张三",
      age:18,
      sex:"男"
  }
  //控制台打印user对象
  console.log(user)

  //将js对象转换为JSon字符串
  var str=JSON.stringify(user);
  console.log(str);
  //将JSON字符串转为js对象
  var user1=JSON.parse(str);
  console.log(user1)

  //这是一个对象键值对存在的
  var object={a:"Hello",b:"Json"};
  console.log(object)
  //这是一个JSON字符串,本质是一个字符串
  var json='{"a":"Hello","b":"Json"}';
  console.log(json)
  //将对象转为json字符串
  var objectjson=JSON.stringify({a:"Hello",b:"Json"});
  console.log(objectjson)
  //将json字符串转换为对象
  var jsonobject=JSON.parse('{"a":"Hello","b":"Json"}');
  console.log(jsonobject)
</script>
  </body>
</html>

2.Jackson使用

jackson是json的解析工具

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.12.0</version>
</dependency>

2.将对象转为json字符串

@Controller
public class Test {
    @RequestMapping("/json1")
    @ResponseBody//不走视图解析器
    public String jsontest()  {
        //创建一个jackson的对象映射器,用来解析数据
        ObjectMapper mapper = new ObjectMapper();
        //创建对象
        User user = new User("张三", 12, "男");
        //将对象解析为json格式
        //由于注解@``  ` ` ResponseBody这里会将str转换为json格式返回
           String string = null;
        try {
                string = mapper.writeValueAsString(user);
                } catch (JsonProcessingException e) {
                e.printStackTrace();
                }

             return string;
     }
  }

3.将日期转为json字符串

@Controller
public class Test {
    @RequestMapping("/json1")
    @ResponseBody//不走视图解析器
    public String jsontest()  {
         ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        mapper.setDateFormat(format);
        Date date = new Date();

        //User user = new User("张三", 12, "男");
        String string = null;
        try {
                string = mapper.writeValueAsString(date);
                } catch (JsonProcessingException e) {
                e.printStackTrace();
                }

                return string;
                }

                }

3.将其写为工具类JsonUtils

JsonUtil.java:工具类中使用方法的重载,里面的业务需求不需要在写直接调用,给不需要的传递的参数传为null即可


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

import java.text.SimpleDateFormat;

public class JsonUtil {
    public static String getjson(Object o) {
        String string = getjson(o, null);
        return string;
    }

    public static String getjson(Object o, SimpleDateFormat format)  {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.setDateFormat(format);
        String string=null;
        try {
           string = mapper.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return string;
    }
}

测试:

import com.mahui.pojo.User;
import com.mahui.utils.JsonUtil;
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.Date;

@Controller
public class Test2 {
    @RequestMapping("/json2")
    @ResponseBody
    public String test1(){
        User user = new User("李四", 15, "女");

        String string = JsonUtil.getjson(user);
        System.out.println(string);
        return string;
    }
    @RequestMapping("/json3")
    @ResponseBody
    public String test2(){


        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String string = JsonUtil.getjson(date, format);
        return string;
    }
}

3.Fastjson使用

1.导入jar包

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

2.测试:

import com.alibaba.fastjson.JSON;
import com.mahui.pojo.User;
import java.util.ArrayList;
public class FastJsonTest {
    public static void main(String[] args) {

        User user1 = new User("张三1", 45, "男");
        User user2 = new User("张三2", 45, "男");
        User user3 = new User("张三3", 45, "男");
        User user4 = new User("张三4", 45, "男");
        User user5 = new User("张三5", 45, "男");

        ArrayList<User> userlist = new ArrayList<User>();
        userlist.add(user1);
        userlist.add(user2);
        userlist.add(user3);
        userlist.add(user4);
        userlist.add(user5);

        String string = JSON.toJSONString(userlist);
        System.out.println(string);
    }
}

10.拦截器

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

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

过滤器

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

拦截器

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

如何实现拦截器?

想要自定义拦截器,必须实现 HandlerInterceptor 接口。

11.登陆判断验证

拦截用户的请求,判断用户是否登陆。如果用户登陆。放行,如果用户未登陆,跳转到登陆页面。

  1. 编写一个登陆页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>
    
        <form action="${pageContext.request.contextPath}/user/login" method="post">
           用户名: <input type="text" name="username"/><br>
           密码: <input type="password" name="password"/>
            <input type="submit" name="提交"/>
        </form>
    </h1>
    </body>
    </html>
    
    
  2. 编写一个Controller请求

    package com.mahui.Controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpSession;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
        @RequestMapping("/goLogin")
        public String goLogin(){
            return "login";
        }
        @RequestMapping("/main")
        public String main(){
            return "main";
        }
    
        @RequestMapping("/login")
        public String login(String username, String password, HttpSession session){
            //将用户信息记录在session中
            session.setAttribute("userInfo",username);
            return "main";
        }
    
        @RequestMapping("/loginOut")
        public String loginOut( HttpSession session){
            //session过期
            session.invalidate();
            return "login";
        }
    }
    
    
  3. 编写主页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>首页</h1>
    <a href="${pageContext.request.contextPath}/user/loginOut">退出登录</a>
    </body>
    </html>
    
    
  4. 在index页面上跳转

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
      </head>
      <body>
      <h1>
        <a href="${pageContext.request.contextPath}/user/goLogin">登录页面</a>
      </h1>
      <h1>
        <a href="${pageContext.request.contextPath}/user/main">首页</a>
      </h1>
      </body>
    </html>
    
  5. 编写用户拦截器

    package com.mahui.config;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class UserInterceptor implements HandlerInterceptor {
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            HttpSession session = request.getSession();
            //如果是登陆页面放行
            if(request.getRequestURI().contains("login")){
                return true;
            }
            //如果用户已经登陆放行
            if(session.getAttribute("userInfo")!=null){
                return true;
            }
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
            return false;
        }
    }
    
    
  6. 配置用户拦截器

     <mvc:interceptor>
                <!--包括这个请求下的所有请求-->
                <mvc:mapping path="/user/**"/>
                <bean class="com.mahui.config.UserInterceptor"/>
            </mvc:interceptor>
    
  7. 启动tomcat进行测试

原文地址:https://blog.csdn.net/weixin_42093672/article/details/115149808

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


开发过程中是不可避免地会出现各种异常情况的,例如网络连接异常、数据格式异常、空指针异常等等。异常的出现可能导致程序的运行出现问题,甚至直接导致程序崩溃。因此,在开发过程中,合理处理异常、避免异常产生、以及对异常进行有效的调试是非常重要的。 对于异常的处理,一般分为两种方式: 编程式异常处理:是指在代
说明:使用注解方式实现AOP切面。 什么是AOP? 面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 通俗描述:不通过修改源代码方式,在主干功能里面添加新功能。 AOP底层使用动态代理。 AOP术语 连接点
Spring MVC中的拦截器是一种可以在请求处理过程中对请求进行拦截和处理的机制。 拦截器可以用于执行一些公共的操作,例如日志记录、权限验证、数据转换等。在Spring MVC中,可以通过实现HandlerInterceptor接口来创建自定义的拦截器,并通过配置来指定拦截器的应用范围和顺序。 S
在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在同一 Web 应用程序的多个组件中进行共享和访问。常见的共享域有四种:ServletContext、HttpSession、HttpServletRequest、PageContext。 ServletContext 共享域:
文件上传 说明: 使用maven构建web工程。 使用Thymeleaf技术进行服务器页面渲染。 使用ResponseEntity实现下载文件的功能。 @Controller public class FileDownloadAndUpload { @GetMapping(&quot;/file/d
创建初始化类,替换web.xml 在Servlet3.0环境中,Web容器(Tomcat)会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。 Spring提供了这个接口的实现,名为SpringS
在 Web 应用的三层架构中,确保在表述层(Presentation Layer)对数据进行检查和校验是非常重要的。正确的数据校验可以确保业务逻辑层(Business Logic Layer)基于有效和合法的数据进行处理,同时将错误的数据隔离在业务逻辑层之外。这有助于提高系统的健壮性、安全性和可维护
什么是事务? 事务(Transaction)是数据库操作最基本单元,逻辑上一组操作,要么都成功,要么都失败,如果操作之间有一个失败所有操作都失败 。 事务四个特性(ACID) 原子性 一组操作要么都成功,要么都失败。 一致性 一组数据从事务1合法状态转为事务2的另一种合法状态,就是一致。 隔离性 事
什么是JdbcTemplate? Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。 准备工作 引入jdbcTemplate的相关依赖: 案例实操 创建jdbc.properties文件,配置数据库信息 jdbc.driver=com.mysql.cj.
SpringMVC1.MVC架构MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范是将业务逻辑、数据、显示分离的方法来写代码MVC主要作用是:降低了视图和业务逻辑之间的双向耦合MVC是一个架构模型,不是一种设计模式。1.model(模型)数据模型,提供要展示的数据,因此包
SpringMVC学习笔记1.SpringMVC应用1.1SpringMVC简介​SpringMVC全名叫SpringWebMVC,是⼀种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于SpringFrameWork的后续产品。​MVC全名是ModelViewController,是模型(model)-视图(view)-控制器(co
11.1数据回显基本用法数据回显就是当用户数据提交失败时,自动填充好已经输入的数据。一般来说,如果使用Ajax来做数据提交,基本上是没有数据回显这个需求的,但是如果是通过表单做数据提交,那么数据回显就非常有必要了。11.1.1简单数据类型简单数据类型,实际上框架在这里没有
一、SpringMVC简介1、SpringMVC中重要组件DispatcherServlet:前端控制器,接收所有请求(如果配置/不包含jsp)HandlerMapping:解析请求格式的.判断希望要执行哪个具体的方法.HandlerAdapter:负责调用具体的方法.ViewResovler:视图解析器.解析结果,准备跳转到具体的物
1.它们主要负责的模块Spring主要应用于业务逻辑层。SpringMVC主要应用于表现层。MyBatis主要应用于持久层。2.它们的核心Spring有三大核心,分别是IOC(控制反转),DI(依赖注入)和AOP(面向切面编程)。SpringMVC的核心是DispatcherServlet(前端控制器)。MyBatis的核心是ORM(对
3.注解开发Springmvc1.使用注解开发要注意开启注解支持,2.注解简化了,处理映射器和处理适配器,只用去管视图解析器即可案例代码:1.web.xml,基本不变可以直接拿去用<!--调用DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name>
拦截器概述SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。**过滤器与拦截器的区别:**拦截器是AOP思想的具体应用。过滤器servlet规范中的一部分,任何javaweb工程都可以使用
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="
学习内容:1、SSH&SSM2、Spring3、Struts2&SpringMVC4、Hibernate&MyBatis学习产出:1.SSH和SSM都是有Spring框架的,他们两个差不多。2.Spring分为四个模块,持久层,表示层,检测层,还有核心层,核心层分为2个关键核心功能。分别为,控制反转(IOC),依赖注入(DI),和面向切面编程
一、SpringMVC项目无法引入js,css的问题具体原因是css和js等被SpringMVC拦截了:解决方案:在spring-mvc.xml中配置<mvc:default-servlet-handler/><?xmlversion="1.0"encoding="UTF-8"?><beansxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
开发环境:Eclipse/MyEclipse、Tomcat8、Jdk1.8数据库:MySQL前端:JavaScript、jQuery、bootstrap4、particles.js后端:maven、SpringMVC、MyBatis、ajax、mysql读写分离、mybatis分页适用于:课程设计,毕业设计,学习等等系统介绍