SpringMVC学习使用

news2025/2/22 11:32:56

在这里插入图片描述

一、SpringMVC简单理解

1.1 Spring与Web环境集成

1.1.1 ApplicationContext应用上下文获取方式

应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次。

在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象了。

1.1.2 Spring提供获取应用上下文的工具

上面的分析不用手动实现,Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。

所以我们需要做的只有两件事:

①在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)

②使用WebApplicationContextUtils获得应用上下文对象ApplicationContext

1.1.3 导入Spring集成web的坐标

        <!-- spring必要依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <!-- spring web依赖注意使用mvc后倒入webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
        </dependency>
        <!--Jsp坐标-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
        </dependency>
        <!-- Servlet坐标 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

1.1.4 配置ContextLoaderListener监听器

 <!--全局参数-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring的监听器-->
<listener>
	<listener-class>
       org.springframework.web.context.ContextLoaderListener
   </listener-class>
 </listener>

1.1.5 通过工具获得应用上下文对象

@WebServlet(name = "TestServlet", value = "/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        WebApplicationContext spring = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        System.out.println(spring.getBean("user"));
    }
}

知识要点

Spring集成web环境步骤

①配置ContextLoaderListener监听器
②使用WebApplicationContextUtils获得应用上下文
③spring-web提供的监听器spring-webmvc页提供(同时使用会冲突)

1.2 SpringMVC的简介

1.2.1 SpringMVC概述

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。

SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

通过属性java类交由spring容器管理,通过注解定义url实现对应的方法执行,简化了servlet定义与书写

1.2.2 SpringMVC简单实现

使用servlet进行控制层处理每一个请求都需要书写一个servlet,每个servlet只修改处理请求的方法与名称,其余没有修改,springMVC可以看做提供了一个中央控制器对这些servlet进行统一的分发管理并简化servlet的书写

①将所有的方法书写在一个java类中 并书写相应地址映射

import java.util.HashMap;

//将所有需要执行的方法书写在当前类中
public class AllController {
    HashMap<String,String> map=new HashMap<>();

    public void a(){
        System.out.println("a方法执行");
    }

    public void b(){
        System.out.println("b方法执行");
    }
}

②书写核心控制器(应该是处理所有请求的servlet)

@WebServlet("/*")
public class AllServlet extends HttpServlet {
    AllController allController=new AllController();
    @Override
    public void init() throws ServletException {
        HashMap<String, String> map = allController.map;
        map.put("/day0924/a","a");
        map.put("/day0924/b","b");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取实际请求的uri
        String requestURI = request.getRequestURI();
        System.out.println("requestURI:"+requestURI);
        HashMap<String, String> map = allController.map;
        String methodName = map.get(requestURI);

        //通过反射调用对应方法
        Class<AllController> allControllerClass = AllController.class;
        try {
            Method declaredMethod = allControllerClass.getDeclaredMethod(methodName);
            //执行对应方法
            declaredMethod.invoke(allController);
        } catch (Exception e) {
        }
    }
}

1.2.3 SpringMVC快速入门

需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。

开发步骤

①导入SpringMVC相关坐标

②配置SpringMVC核心控制器DispathcerServlet

③创建Controller类和视图页面

④使用注解配置Controller类中业务方法的映射地址

⑤配置SpringMVC核心文件 spring-mvc.xml

⑥客户端发起请求测试

代码实现

①导入Spring和SpringMVC的坐标、导入Servlet和Jsp的坐标

 <!--Spring坐标-->
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>5.0.8.RELEASE</version>
 </dependency>
 <!--SpringMVC坐标-->
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>5.0.8.RELEASE</version>
 </dependency>
    <!--Jsp坐标-->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
    </dependency>
    <!-- Servlet坐标 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

②在web.xml配置SpringMVC的核心控制器与spring加载监听器

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <!-- 配置springmvc前端控制器 -->
    <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>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

③创建Controller和业务方法

public class UserController {


    public ModelAndView select(ModelAndView mv,HttpServletRequest request){
        request.setAttribute("msg","查找返回的数据");
        mv.setViewName("/index.jsp");
        return mv;
    }

    public String update(ModelAndView mv,HttpServletRequest request){
        request.setAttribute("msg","更新返回的数据");
        return "/index.jsp";
    }
}

③创建视图页面index.jsp

<html>
<body>
    <h2>Hello SpringMVC!</h2>
    ${msg}
</body>
</html>

④配置注解

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

    @RequestMapping("/select.do")
    public ModelAndView select(ModelAndView mv,HttpServletRequest request){
        request.setAttribute("msg","查找返回的数据");
        mv.setViewName("/index.jsp");
        return mv;
    }

    @RequestMapping("/update.do")
    public String update(ModelAndView mv,HttpServletRequest request){
        request.setAttribute("msg","更新返回的数据");
        return "/index.jsp";
    }
}

⑤创建spring-mvc.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置注解扫描-->
    <context:component-scan base-package="com.yunhe.controller"/>
</beans>

二、SpringMVC常用功能与使用

2.1 SpringMVC的执行流程

在这里插入图片描述

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

2.1.1 SpringMVC组件解析

  1. 前端控制器:DispatcherServlet
    ​ 用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。

  2. 处理器映射器:HandlerMapping
    ​ HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

  3. 处理器适配器:HandlerAdapter

​ 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

  1. 处理器:Handler
    ​ 它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。

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

  3. 视图:View
    ​ SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

2.1.2 SpringMVC注解解析

@RequestMapping
作用:用于建立请求 URL 和处理请求方法之间的对应关系
位置:
类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径

属性:
value:用于指定请求的URL。它和path属性的作用是一样的
method:用于指定请求的方式
params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样

例如:
​ params = {“accountName”},表示请求参数必须有accountName
​ params = {“moeny!=100”},表示请求参数中money不能是100

2.1.3 SpringMVC的XML配置解析

  1. mvc命名空间引入
命名空间:xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
约束地址:http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
  1. 组件扫描

SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要使用<context:component-scan base-package=“com.yh.controller"/>进行组件扫描。
SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件中配置了默认的视图解析器,如下:

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

翻看该解析器源码,可以看到该解析器的默认设置,如下:

REDIRECT_URL_PREFIX = "redirect:"  --重定向前缀
FORWARD_URL_PREFIX = "forward:"    --转发前缀(默认值)
prefix = "";     --视图名称前缀
suffix = "";     --视图名称后缀
  1. 视图解析器
    我们可以通过属性注入的方式修改视图的的前后缀
<!--配置内部资源视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/views/"></property>
  <property name="suffix" value=".jsp"></property>
</bean>

2.2 SpringMVC的数据响应

数据响应方式

1) 页面跳转
①直接返回字符串
②通过ModelAndView(HttpServletRequest)对象返回

2) 回写数据
①直接返回字符串
②返回对象或集合

页面跳转-返回字符串形式

第一种形式:
在这里插入图片描述

这种方式进行页面跳转一般与HttpServletRequest对象一起使用,在参数列表中声明,将数据存储至作用域中进行传递

第二种形式:

@RequestMapping(value="/quick4")
    public String save4(Model model){
        model.addAttribute("username","二狗子");
        return "success";
    }

这种方式同样会进行页面跳转,但是数据传递使用model对象,model对象的使用方式与HttpServletRequest类似,可以在jsp中使用el表达式通过key进行获取

页面跳转-通过ModelAndView对象返回

在Controller中方法返回ModelAndView对象,并且设置视图名称

@RequestMapping(value="/quick2")
    public ModelAndView save2(){
        /*
            Model:模型 作用封装数据
            View:视图 作用展示数据
         */
        ModelAndView modelAndView = new ModelAndView();
        //设置模型数据
        modelAndView.addObject("username","二狗子");
        //设置视图名称
        modelAndView.setViewName("success");
        return modelAndView;
    }

这种方法就是直接将返回的视图与数据一同交由视图解析器进行自动处理

当然也可以不创建ModelAndView对象而是在方法中声明,在Controller中方法形参上直接声明ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面

 @RequestMapping(value="/quick3")
    public ModelAndView save3(ModelAndView modelAndView){
        modelAndView.addObject("username","华华");
        modelAndView.setViewName("success");
        return modelAndView;
    }

回写数据-直接返回字符串

通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写数据,此时不需要视图跳转,业务方法返回值为void将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架通知视图解析器,方法返回的字符串不是跳转是直接在http响应体中返回

@RequestMapping(value="/quick7")
    @ResponseBody  //告知SpringMVC框架 不进行视图跳转 直接进行数据响应
    public String save7() throws IOException {
        return "hello yh";
    }

    @RequestMapping(value="/quick6")
    public void save6(HttpServletResponse response) throws IOException {
        response.getWriter().print("hello yh");
    }

json字符串也是字符串,所以也可以通过这种方式返回json字符串数据

@RequestMapping(value="/quick8")
    @ResponseBody
    public String save8() throws IOException {
        return "{\"username\":\"zhangsan\",\"age\":18}";
    }

手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串,我们可以使用web阶段学习过的json转换工具类进行转换后回写字符串(一般不用手动转换的方式)

回写数据-返回对象或集合

通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行如下配置:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
            </list>
        </property>
    </bean>
@RequestMapping(value="/quick10")
    @ResponseBody
    //期望SpringMVC自动将User转换成json格式的字符串
    public User save10() throws IOException {
        User user = new User();
        user.setUsername("张三");
        user.setAge(18);
        return user;
    }

这样配置还是比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置

<mvc:annotation-driven/>

在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
使用<mvc:annotation-driven />自动加载 RequestMappingHandlerMapping(处理映射器)和RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用<mvc:annotation-driven />替代注解处理器和适配器的配置。同时使用<mvc:annotation-driven />默认底层就会集成jackson进行对象或集合的json格式字符串的转换

2.3 SpringMVC的数据请求

客户端请求参数的格式是:name=value&name=value……
服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数
①基本类型参数
②类类型参数
③数组类型参数
④集合类型参数

2.3.1 基本类型参数的获取

springmvc会自动进行解析,只需要在controller中的业务方法的参数名称与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型转换;
自动的类型转换是指从String向其他类型的转换(注意类型转换失败的情况)

@RequestMapping(value="/quick11")
    @ResponseBody
    public void save11(String username,int age){
        System.out.println(username);
        System.out.println(age);
    }

Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。

当然也可以手动的进行配置获取请求指定的参数,使用RequestParam注解
@RequestParam有以下三个参数:
value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将抛出异常;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,设置该参数时,自动将required设为false。

public String requestparam(@RequestParam(value="username",required=false) String username)

2.3.2 类类型参数的获取

package com.yunhe.pojo;
public class User {
    private String username;
    private int age;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}

@RequestMapping(value="/quick12")
    @ResponseBody
    public void save12(User user){
        System.out.println(user);
    }

2.3.3 数组类型参数的获取

在前台页面提交的数据中,多个数据name相同,springmvc会自动解析成数组,但要求controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。

@RequestMapping(value="/quick13")
    @ResponseBody
    public void save13(String[] strs) throws IOException {
        System.out.println(Arrays.asList(strs));
    }

2.3.4 集合类型参数的获取

springmvc会自动将对个name相同的数据解析为数组,所以在进行集合获取时需要将集合参数包装到一个POJO中才可以。

<form action="${pageContext.request.contextPath}/user/quick14" method="post">
        <%--表明是第一个User对象的username age--%>
        <input type="text" name="userList[0].username"><br/>
        <input type="text" name="userList[0].age"><br/>
        <input type="text" name="userList[1].username"><br/>
        <input type="text" name="userList[1].age"><br/>
        <input type="submit" value="提交">
    </form>

package com.yh.domain;

import java.util.List;

public class VO {
    private List<User> userList;
    public List<User> getUserList() {
        return userList;
    }
    public void setUserList(List<User> userList) {
        this.userList = userList;
    }
    @Override
    public String toString() {
        return "VO{" +
                "userList=" + userList +
                '}';
    }
}

@RequestMapping(value="/quick14")
    @ResponseBody
    public void save14(VO vo) throws IOException {
        System.out.println(vo);
    }

这种使用方式太过繁琐,对于不同的pojo类需要创建对应的集合类

使用ajax提交json数据获取集合类型参数数据

当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装

<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
    <script>
        var userList = new Array();
        userList.push({username:"zhangsan",age:18});
        userList.push({username:"lisi",age:28});

        $.ajax({
            type:"POST",
            url:"${pageContext.request.contextPath}/user/quick15",
            data:JSON.stringify(userList),
            contentType:"application/json;charset=utf-8"
        });

    </script>

@RequestMapping(value="/quick15")
    @ResponseBody
    public void save15(@RequestBody List<User> userList) throws IOException {
        System.out.println(userList);
    }

2.4 SpringMVC静态资源的访问

当有静态资源需要加载时,比如jquery文件,通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源:

•在spring-mvc.xml配置文件中指定放行的资源

<mvc:resources mapping="/js/**"location="/js/"/>

•使用<mvc:default-servlet-handler/>标签

<!--开发资源的访问-->
    <!--<mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/img/**" location="/img/"/>-->

    <mvc:default-servlet-handler/>

2.5 SpringMVC配置编码过滤器

使用springmvc与servlet一样,当编码不一致时会出现乱码问题,springmvc提供了CharacterEncodingFilter全局过滤器进行全局的编码配置

<!--配置全局过滤的filter-->
    <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>

2.6 SpringMVC配置参数绑定

当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显式的绑定

<form action="${pageContext.request.contextPath}/quick16" method="post">
    <input type="text" name="name"><br>
    <input type="submit" value="提交"><br>
</form>


@RequestMapping(value="/quick16")
    @ResponseBody
    public void save16(@RequestParam(value="name",required = false,defaultValue = "yh") String username) throws IOException {
        System.out.println(username);
    }

属性:
value :页面数据的name
required :是否必填(如果页面没有传递则报错默认为false)
defaultValue :默认值,当页面没有传递数据时的赋值(默认为数据 类型默认值)

2.7 SpringMVC配置请求类型转换器

SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。
但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。

@component
public class DateConverter implements Converter<String, Date> {
    public Date convert(String dateStr) {
        //将日期字符串转换成日期对象 返回
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = format.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

@RequestMapping(value="/quick18")
    @ResponseBody
    public void save18(Date date) throws IOException {
        System.out.println(date);
    }

    <mvc:annotation-driven conversion-service="conversionService"/>
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <ref bean="dateConverter"/>
            </set>
        </property>
    </bean>

2.8 请求头信息信息的获取

使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
value:请求头的名称
required:是否必须携带此请求头

@RequestMapping(value="/quick20")
    @ResponseBody
    public void save20(@RequestHeader(value = "User-Agent",required = false) String user_agent) throws IOException {
        System.out.println(user_agent);
    }

2.9 请求头cookie数据的获取

使用@CookieValue可以获得指定Cookie的值
@CookieValue注解的属性如下:
value:指定cookie的名称
required:是否必须携带此cookie

    @RequestMapping(value="/quick21")
    @ResponseBody
    public void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {
        System.out.println(jsessionId);
    }

三、SpringMVC使用RESTful风格参数的获取

Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。

Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
GET:用于获取资源
POST:用于新建资源
PUT:用于更新资源
DELETE:用于删除资源

例如:
/user/1 GET : 得到 id = 1 的 user
/user/1 DELETE: 删除 id = 1 的 user
/user/1 PUT: 更新 id = 1 的 user
/user POST: 新增 user

上述url地址/user/1中的1就是要获得的请求参数,form表单提交数据的方式支持get与post,但是在SpringMVC中可以使用占位符进行参数绑定。地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。

http://localhost:8080/springmvc1/quick17/zhangsan

@RequestMapping(value="/quick17/{name}")
@ResponseBody
 public void save17(@PathVariable(value="name") String username) throws IOException {
        System.out.println(username);
 }

springmvc使用RESTful风格就是使用占位符的形式,将数据与地址进行绑定,通过@PathVariable注解进行获取,完成通过对不同路径请求完成类似功能的需求

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用axios发送不同的请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="js/axios.min.js"></script>
</head>
<body>
    <button id="btn1">GET请求</button>
    <button id="btn2">POST请求</button>
    <button id="btn3">PUT请求</button>
    <button id="btn4">DELETE请求</button>
</body>
<script>
    document.getElementById("btn1").onclick=function (){
        var obj={};
        axios({
            // 请求方式
            method: 'get',
            url: 'user/1',
            // 传递参数 data使用流发送数据 params台servlet可以直接获取
            data: obj,
            //响应的数据格式 默认就是json 可以省略
            responseType: 'text'
        }).then(response => {
            // 请求成功
            let res = response.data;
            console.log(res);
        }).catch(error => {
            // 请求失败,
            console.log(error);
            // 一般不用
        });
    }
    document.getElementById("btn2").onclick=function (){
        var obj={id:2,name:"张三"};
        axios({
            // 请求方式
            method: 'post',
            url: 'user',
            // 传递参数 data使用流发送数据 params台servlet可以直接获取
            data: obj,
            //响应的数据格式 默认就是json 可以省略
            responseType: 'json'
        }).then(response => {
            // 请求成功
            let res = response.data;
            console.log(res);
        }).catch(error => {
            // 请求失败,
            console.log(error);
            // 一般不用
        });
    }

    document.getElementById("btn3").onclick=function (){
        var obj={id:2,name:"张三2"};
        axios({
            // 请求方式
            method: 'put',
            url: 'user',
            // 传递参数 data使用流发送数据 params台servlet可以直接获取
            data: obj,
            //响应的数据格式 默认就是json 可以省略
            responseType: 'json'
        }).then(response => {
            // 请求成功
            let res = response.data;
            console.log(res);
        }).catch(error => {
            // 请求失败,
            console.log(error);
            // 一般不用
        });
    }
    document.getElementById("btn4").onclick=function (){
        var obj={};
        axios({
            // 请求方式
            method: 'delete',
            url: 'user/4',
            // 传递参数 data使用流发送数据 params台servlet可以直接获取
            data: obj,
            //响应的数据格式 默认就是json 可以省略
            responseType: 'text'
        }).then(response => {
            // 请求成功
            let res = response.data;
            console.log(res);
        }).catch(error => {
            // 请求失败,
            console.log(error);
            // 一般不用
        });
    }
</script>
</html>

四、SpringMVC拦截器简单使用

4.1 概念

SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
(1)过滤器:

依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。

(2)拦截器:

依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。

1、常见应用场景

1)日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

2)权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;

3)性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

4)通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

5)OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。

…………本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。

SpringMVC提供的拦截器接口:HandlerInterceptor

public interface HandlerInterceptor {
	boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
	    throws Exception;
 
	void postHandle(
			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
			throws Exception;
 
	void afterCompletion(
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception;
}

拦截器一个有3个回调方法,而一般的过滤器Filter才两个:

preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;

postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器才会执行afterCompletion。

拦截器适配器:HandlerInterceptorAdapter

有时我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor接口的话,三个方法必须实现,此时spring提供了一个HandlerInterceptorAdapter适配器(一种适配器设计模式的实现),允许我们只实现需要的回调方法

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception {
		return true;
	}
 
	public void postHandle(
			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
			throws Exception {
	}
 
	public void afterCompletion(
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
	}
 
	public void afterConcurrentHandlingStarted(
			HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
	}
}

4.2 简单使用

①自定义两个拦截器(继承拦截器适配器:HandlerInterceptorAdapter):HandlerInterceptor1 和 HandlerInterceptor2

public class HandlerInterceptor1 extends HandlerInterceptorAdapter{
 
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("--1--HandlerInterceptor1.preHandle");
		return true;
	}
 
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("--1--HandlerInterceptor1.postHandle");
	}
 
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("--1--HandlerInterceptor1.afterCompletion");
	}
}

②在 springmvc.xml 配置文件中配置拦截器:
(1)拦截所有Controller类里的所有处理方法

	<!-- 配置拦截器:-->
	<mvc:interceptors>
		<!-- 会拦截所有Controller类里的所有处理方法 -->
		<bean class="com.yunhe.interceptor.HandlerInterceptor1"></bean>
		<bean class="com.yunhe.interceptor.HandlerInterceptor2"></bean>
	</mvc:interceptors>

(2)只拦截某个请求路径的处理方法

	<!-- 配置拦截器:-->
	<mvc:interceptors>
		<!-- 会拦截所有Controller类里的所有处理方法 -->
		<bean class="com.yunhe.interceptor.HandlerInterceptor1"></bean>
		<mvc:interceptor>
			<!-- 只拦截该路径 -->
			<mvc:mapping path="/users"/>
			<bean class="com.yunhe.interceptor.HandlerInterceptor2"></bean>
		</mvc:interceptor>
	</mvc:interceptors>


(3)拦截器深入配置:注意 /** (任意分层路径下) ,/* (该任意单路径下) 和 配置順序(先所有后排除)

	<!-- 配置拦截器:-->
	<mvc:interceptors>
		<!-- 会拦截所有Controller类里的所有处理方法 -->
		<bean class="com.yunhe.interceptor.HandlerInterceptor1"></bean>
		<mvc:interceptor>
			<!-- 只拦截该路径 -->
			<mvc:mapping path="/users"/>
			<bean class="com.yunhe.interceptor.HandlerInterceptor2"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
			<!-- 拦截所有请求,排除拦截 /toAdd 请求 -->
			<mvc:mapping path="/**"/>
			<mvc:exclude-mapping path="/toAdd"/>
			<bean class="com.yunhe.interceptor.HandlerInterceptor3"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

# 五、SSM整合项目创建

①导入相应的依赖坐标

    <!-- spring核心依赖坐标 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.5</version>
    </dependency>

    <!-- springaop织入依赖 -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.6</version>
    </dependency>

    <!-- lombok工具依赖 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.2</version>
    </dependency>


    <!-- spring jdbc依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.5</version>
    </dependency>

    <!-- mysql依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.39</version>
    </dependency>
 
    <!-- Druid连接池 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.10</version>
    </dependency>

    <!-- springmvc依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.5</version>
    </dependency>

    <!-- servlet依赖 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
    
    <!-- jsp依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
    </dependency>

    <!-- jackson依赖 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>

    
    <!-- mybatis依赖 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.6</version>
    </dependency>

    <!--  mybatis sping整合依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.6</version>
    </dependency>
    
    <!--log4j依赖-->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

②创建相应的包

在这里插入图片描述

③书写mybatis核心配置文件

<?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>
    <!-- 加载properties配置文件 -->
    <!--<properties url=""></properties>-->
    
    <!-- 为指定的包下的类设置别名(设置pojo 使用首字母小写形式的别名) -->
    <!--<typeAliases>
        <package name=""/>
    </typeAliases>-->

    <!-- 配置mybatis数据源选择操作 -->
    <!--<environments default="">
        <environment id="">
            <transactionManager type=""></transactionManager>
            <dataSource type=""></dataSource>
        </environment>
    </environments>-->
    
    
    <!-- mybatis的全局配置 基本使用默认 其他可以通过mapper配置文件进行设置 -->
    <settings>
        <setting name="lazyLoadingEnabled" value="true"/><!-- 开启懒加载 -->
        <setting name="aggressiveLazyLoading" value="false"/><!-- 设置懒加载侵入方式 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/><!-- 使用mybatis 自带的日志管理 -->
    </settings>
    
    <!-- 配置mybatis扫描xml文件所在的包 -->
    <!--<mappers>
        <package name=""/>
    </mappers>-->

</configuration>

④书写log4j与数据连接配置文件

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

⑤配置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"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
    <!-- spring组件扫描 -->
    <!-- 将含有对应注解的类交由spring管理 可以实现IOC与DI AOP也必须切入由spring管理的类 -->
    <context:component-scan base-package="com.yunhe"/>
    
    <!-- 加载properties -->
    <!-- 可以在当前的配置文件中使用${key}的形式获取对应的value值 -->
    <context:property-placeholder location="classpath:db.properties"/>
    
    <!-- 配置数据源 -->
    <!-- 使用指定的连接池对数据源进行管理 -->
    <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}"/>
    </bean>

    <!-- 配置spring与mybatis整合 -->
    <!-- 配置SqlSessionFactoryBean对象,整合加载mybatis配置文件 使用mybatis进行数据源操作 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 将数据源交由mybatis进行管理 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置mybatis配置文件 -->
        <!-- 加载mybatis核心配置文件(进行修改时) -->
        <property name="configLocation" value="classpath:mybatis.xml"/>
        <!-- 配置mapper映射文件 -->
        <!-- 在创建mybatis时加载所有的mapper.xml -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>

    </bean>


    <!-- mybatis.spring自动映射,DAO接口所在包名,Spring会自动查找其下的类 -->
    <!-- 根据加载的mapper.xml创建相应的实现类 并交由spring容器管理 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.yunhe.mapper" />
    </bean>
    
    <!--平台事务管理器-->
    <!-- 创建相应的事务代理对象交由spring容器管理 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 开启事务的注解驱动 -->
    <!-- 将拥有事务处理的方法进行事务代理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    <!-- 设置aop织入自动代理 -->
    <!-- 才会将相应的切面类织入指定的切入点(方法) -->
    <aop:aspectj-autoproxy/>
    
    <!-- springmvc视图解析器 -->
    <!-- 在controller返回的视图名进行拼接返回对应视图 -->
    <!-- 如果需要使用其他的视图模板或插件也是在视图解析器进行配置 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 开启springmvc注解驱动 -->
    <mvc:annotation-driven/>

    <!-- 开启静态资源默认过滤 -->
    <mvc:default-servlet-handler/>
    
    <!-- 指定静态资源过滤 -->
     <!--<mvc:resources mapping="" location=""></mvc:resources>-->
    
</beans>

⑥配置web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>


  <!-- springmvc编码控制器 -->
  <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>


  <!-- springmvc前端控制器 -->
  <servlet>
    <servlet-name>mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>mvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

⑦书写相应的代码测试ssm整合是否成功

User.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int uid;
    private String uusername;
    private String upassword;
}

UserMapper.java

public interface UserMapper {
    ArrayList<User> selectAll();
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunhe.mapper.UserMapper">
    
    
    <select id="selectAll" resultType="com.yunhe.pojo.User">
        select * from user
    </select>
    
    
</mapper>

UserService.java

public interface UserService {
    public ArrayList<User> findAll();
}

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public ArrayList<User> findAll() {
        return userMapper.selectAll();
    }
}

UserController.java

@Controller
public class UserController {
    @Autowired
    private UserService userServiceImpl;
    @RequestMapping("/all")
    public String find(HttpServletRequest request){
        request.setAttribute("msg",userServiceImpl.findAll());
        return "success";
    }
}

success.jsp

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

UserController.java

@Controller
public class UserController {
    @Autowired
    private UserService userServiceImpl;
    @RequestMapping("/all")
    public String find(HttpServletRequest request){
        request.setAttribute("msg",userServiceImpl.findAll());
        return "success";
    }
}

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>
<select id="selectAll" resultType="com.yunhe.pojo.User">
    select * from user
</select>
```

UserService.java

public interface UserService {
    public ArrayList<User> findAll();
}

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public ArrayList<User> findAll() {
        return userMapper.selectAll();
    }
}

UserController.java

@Controller
public class UserController {
    @Autowired
    private UserService userServiceImpl;
    @RequestMapping("/all")
    public String find(HttpServletRequest request){
        request.setAttribute("msg",userServiceImpl.findAll());
        return "success";
    }
}

success.jsp

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

UserController.java

@Controller
public class UserController {
    @Autowired
    private UserService userServiceImpl;
    @RequestMapping("/all")
    public String find(HttpServletRequest request){
        request.setAttribute("msg",userServiceImpl.findAll());
        return "success";
    }
}

success.jsp

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

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

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

相关文章

运维-自动访问系统并截图

需求背景 因项目甲方要求需要对系统进行巡检&#xff0c;由于系统服务器较多&#xff0c;并且已经采用PrometheusGrafana对系统服务器进行管理&#xff0c;如果要完成该任务&#xff0c;需要安排一个人力对各个系统和服务器进行一一截图等操作&#xff0c;费时费力&#xff0c…

在CodeBlocks搭建SDL2工程虚拟TFT彩屏解码带压缩形式的Bitmap(BMP)图像显示

在CodeBlocks搭建SDL2工程虚拟TFT彩屏解码带压缩形式的Bitmap BMP图像显示 参考文章文章说明一、创建和退出SDL2二、 Bitmap(BMP)图片解码图三、Bitmap解码初始化四、测试代码五、主函数六、测试结果 参考文章 解码带压缩形式的Bitmap(BMP)图像并使用Python可视化解码后实际图…

mapbox进阶,添加绘图扩展插件,绘制任意方向矩形

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图扩…

初阶c语言(循环语句习题,完结)

前言&#xff1a; c语言为b站鹏哥&#xff0c;嗯对应视频37集 昨天做的c语言&#xff0c;今天在来做一遍&#xff0c;发现做错了 今天改了平均值的计算&#xff0c; 就是说最大值加上最小值&#xff0c;如果说这个数值非常大的话&#xff0c;两个值加上会超过int类型的最大…

提升编程效率,体验智能编程助手—豆包MarsCode一键Apply功能测评

提升编程效率&#xff0c;体验智能编程助手—豆包MarsCode一键Apply功能测评 &#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 目录 引言豆包…

【deepseek-r1本地部署】

首先需要安装ollama,之前已经安装过了&#xff0c;这里不展示细节 在cmd中输入官网安装命令&#xff1a;ollama run deepseek-r1:32b&#xff0c;开始下载 出现success后&#xff0c;下载完成 接下来就可以使用了&#xff0c;不过是用cmd来运行使用 可以安装UI可视化界面&a…

多用户商城系统的客服管理体系建设

多用户商城系统的运营&#xff0c;客服管理体系建设至关重要。优质的客服服务不仅能提升用户购物体验&#xff0c;还能增强用户对商城的信任与忠诚度&#xff0c;进而促进商城业务的持续增长。以下从四个关键方面探讨如何建设完善的客服管理体系&#xff0c;信息化客服系统在其…

C++设计模式 - 模板模式

一&#xff1a;概述 模板方法&#xff08;Template Method&#xff09;是一种行为型设计模式。它定义了一个算法的基本框架&#xff0c;并且可能是《设计模式&#xff1a;可复用面向对象软件的基础》一书中最常用的设计模式之一。 模板方法的核心思想很容易理解。我们需要定义一…

CZML 格式详解,javascript加载导出CZML文件示例

示例地址&#xff1a;https://dajianshi.blog.csdn.net/article/details/145573994 CZML 格式详解 1. 什么是 CZML&#xff1f; CZML&#xff08;Cesium Zipped Markup Language&#xff09;是一种基于 JSON 的文件格式&#xff0c;用于描述地理空间数据和时间动态场景。它专…

OpenAI推出全新AI助手“Operator”:让人工智能帮你做事的新时代!

引言 随着人工智能技术的不断发展&#xff0c;OpenAI 再次推出令人兴奋的功能——Operator&#xff0c;一个全新的 AI 助手平台。这不仅仅是一个普通的助手&#xff0c;它代表了人工智能技术的又一次飞跃&#xff0c;将改变我们工作和生活的方式。 什么是“Operator”&#xff…

重看Spring聚焦BeanFactory分析

目录 一、理解BeanFactory &#xff08;一&#xff09;功能性理解 &#xff08;二&#xff09;BeanFactory和它的子接口 &#xff08;三&#xff09;BeanFactory的实现类 二、BeanFactory根接口 &#xff08;一&#xff09;源码展示和理解 &#xff08;二&#xff09;基…

将Docker容器打包成镜像提交

前言 Docker 是一个开源软件&#xff0c;也是一个开放平台&#xff0c;用于开发应用、交付&#xff08;shipping&#xff09;应用、运行应用。 Docker允许用户将基础设施&#xff08;Infrastructure&#xff09;中的应用单独分割出来&#xff0c;形成更小的颗粒&#xff08;容…

一文通俗理解为什么需要泛型以及泛型的使用

为什么需要泛型&#xff1f; public static void main(String[] args) {ArrayList list new ArrayList();// 由于集合没有做任何限定&#xff0c;任何类型都可以给其中存放list.add("abc");list.add("def");list.add(5);Iterator it list.iterator();wh…

Sam Altman 揭秘 OpenAI 未来蓝图:GPT-4.5、GPT-5 与模型规范重大更新

OpenAI CEO Sam Altman 近日在 X 平台&#xff08;原 Twitter&#xff09;上分享了关于 GPT-4.5 (代号 “Orion”) 和 GPT-5 的最新进展&#xff0c;同时公布了 OpenAI 模型规范&#xff08;Model Spec&#xff09;的重大更新&#xff0c;强调知识自由与模型行为准则。 核心亮…

老牌系统工具箱,现在还能打!

今天给大家分享一款超实用的电脑软硬件检测工具&#xff0c;虽然它是一款比较“资深”的软件&#xff0c;但依然非常好用&#xff0c;完全能满足我们的日常需求。 电脑软硬件维护检测工具 功能强大易用 这款软件非常贴心&#xff0c;完全不需要安装&#xff0c;直接打开就能用…

在vivado中对数据进行延时,时序对齐问题上的理清

在verilog的ISP处理流程中&#xff0c;在完成第一个模块的过程中&#xff0c;我经常感到困惑&#xff0c;到底是延时了多少个时钟&#xff1f;今日对这几个进行分类理解。 目录 1.输入信号激励源描述 1.1将数据延时[9]个clk 1.2将vtdc与hzdc延时[9]个clk(等价于单bit的数据…

链表 —— 常用技巧与操作总结详解

引言 链表作为一种动态数据结构&#xff0c;以其灵活的内存管理和高效的插入删除操作&#xff0c;在算法与工程实践中占据重要地位。然而&#xff0c;链表的指针操作复杂&#xff0c;容易引发内存泄漏和野指针问题。本文博主将从基础操作到高阶技巧&#xff0c;系统化解析链表的…

Linux下学【MySQL】常用函数助你成为数据库大师~(配sql+实操图+案例巩固 通俗易懂版~)

绪论​ 每日激励&#xff1a;“唯有努力&#xff0c;才能进步” 绪论​&#xff1a; 本章是MySQL中常见的函数&#xff0c;利用好函数能很大的帮助我们提高MySQL使用效率&#xff0c;也能很好处理一些情况&#xff0c;如字符串的拼接&#xff0c;字符串的获取&#xff0c;进制…

[c语言日寄]在不完全递增序中查找特定要素

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…

HtmlRAG:RAG系统中,HTML比纯文本效果更好

HtmlRAG 方法通过使用 HTML 而不是纯文本来增强 RAG 系统中的知识表示能力。通过 HTML 清洗和两步块树修剪方法&#xff0c;在保持关键信息的同时缩短了 HTML 文档的长度。这种方法优于现有基于纯文本的RAG的性能。 方法 其实主要看下围绕html提纯思路&#xff0c;将提纯后的…