Java零基础——SpringMVC篇

1.SpringMVC介绍

SpringMVC是Spring框架中的一个组件,是一个轻量级的web的MVC框架,充当controller,其本质就是一个Servlet。

1.1 传统Servlet的不足

每个请求,都需要定义一个Servlet。虽然可以在service方法中,根据业务标识进行业务分发,但是每个Servlet中的service方法的实现是重复。如果想要对service进行更高层次的封装,就可以解决service的重复代码问题。

每个请求的参数,都需要根据request对象,从Map逐一的获取,单调且含量低。将所有的参数,自动封装映射,简化开发。

request.getParameter(“”)

每个Servlet,向客户端返回数据时,需要单独的处理。

request.getRequestDispatcher(“/路径”).forward(request,response)

Response.sendRedirect(“/路径”)

针对于Servlet在实际使用中的不便,Spring中提供了组件,SpringMVC,更进一步的简化了Servlet的开发。

1.2 SpringMVC的架构

在这里插入图片描述

1.2.1 DispatcherServlet
核心控制器,本质上就是一个Servlet,处理所有的客户端的请求。根据请求的资源路径,在处理器映射器中查找对应的处理器。

1.2.2 HandlerMapping
处理器映射器,存储所有当前程序中的处理器,如果在处理器映射器中查找不到资源路径,直接返回404。

1.2.3 HandlerAdapter
处理器适配器,用于适配各种处理器,调用具体的处理器程序。

1.2.4 Handler
具体处理器,开发者实现相应接口或者使用注解声明的程序。用于处理具体的请求。

1.2.5 ViewResolver
视图解析器,根据处理器返回的数据,进行数据处理,将数据处理成相应的格式。

JSP/JSON等等。

2.SpringMVC使用

2.1 SpringMVC入门使用

2.1.1 导入SpringMVC相关jar包

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>01-mvc01</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!-- 引入springmvc 相关jar包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.0.RELEASE</version></dependency></dependencies>
</project>

2.1.2 编写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"><!-- 配置了一个自定义的处理器 --><bean id="controller01" name="/controller01.do"  class="com.bjpowernode.controller.Controller01"></bean><bean id="controller02" name="/controller02.do"  class="com.bjpowernode.controller.Controller02"></bean><!-- 开启springmvc 注解 --><!-- 开启组件扫描 --><context:component-scan base-package="com.*" /><!-- 开启springmvc 相关注解 --><mvc:annotation-driven />
</beans>

2.1.3 编写相关类

package com.bjpowernode.controller;import org.springframework.web.HttpRequestHandler;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class Controller01 implements HttpRequestHandler {@Overridepublic void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {System.out.println("你好啊 springmvc");}
}package com.bjpowernode.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 Controller02 implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {System.out.println("Hello SpringMVC  02");//模型视图//模型就是数据//视图 界面ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("name","Hello SpringMVC");modelAndView.setViewName("/index.html");//springmvc中 /表示当前项目return modelAndView;}
}package com.bjpowernode.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping
public class Controller03 {@RequestMapping("hello1.do")public String hello(String name){System.out.println("name:"+name);System.out.println("你好springmvc");return "/index.html";}@RequestMapping("hello2.do")public String hello1(String name){System.out.println("name:"+name);System.out.println("你好springmvc");return "/index.html";}
}

2.1.4 在web.xml中配置SpringMVC

<!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><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:springmvc.xml</param-value></init-param><!-- 配置服务器启动时 就初始化DispatcherServlet  --><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
</web-app>

2.1.5 进行测试

使用bean标签的name属性进行访问。注意,每个名字必须有个/,如果多个名字,之间使用逗号。

2.2 SpringMVC的数据绑定

在SpringMVC中为了简化开发,SpringMVC对请求的参数进行预处理,SpringMVC支持按照参数名称,直接将请求参数封装传递给处理器中的方法,处理无需单独的获取。

2.2.1 请求参数
请求参数,是指基本数据类型和字符串、对象、数组、Map等。

2.2.2 获取请求参数

package com.bjpowernode.controller;import com.bjpowernode.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/param")
public class ParamController {/*** 处理简单的参数* @return*/@RequestMapping("/simple.do")public String doSimpleParam(Integer id,boolean flag,String name,@RequestParam("City") String city){System.out.println("id: "+id);System.out.println("flag: "+flag);System.out.println("name: "+name);System.out.println("city: "+city);return  "/success.html";//默认当做内部转发处理  默认当做视图路径}/*** 使用对象接收请求参数*      请求参数的名称 必须 和 对象中属性名一致  类型要支持转换* @param user* @return*/@RequestMapping("/obj.do")public String objParam(User user){System.out.println("id: "+user.getId());System.out.println("flag: "+user.getFlag());System.out.println("name: "+user.getName());return  "/success.html";//默认当做内部转发处理  默认当做视图路径}/*** 使用map接收请求参数*  默认是不支持使用map集合接收数据  需要使用注解@RequestParam*  RequestParam :*      name/value : 绑定请求参数 ,默认根据名称注入值,当名称不一致,可以使用RequestParam设置对应的参数的名称,进行绑定*      required : 是否需要这个参数  默认true 如果有使用了RequestParam这个注解,默认必须传这个参数 如果不是必传 设置为 false*      defaultValue : 如果没有这个请求参数时或者请求参数值为null 设置默认值* @param param* @return*/@RequestMapping("/map.do")public String mapParam(@RequestParam  Map<String,Object> param){System.out.println("id: "+param.get("id"));System.out.println("flag: "+param.get("flag"));System.out.println("name: "+param.get("name"));return  "/success.html";//默认当做内部转发处理  默认当做视图路径}@RequestMapping("/arr.do")public String arr(Integer id,boolean flag,String name,String[] likes){System.out.println("id: "+id);System.out.println("flag: "+flag);System.out.println("name: "+name);List<String> strings = Arrays.asList(likes);System.out.println(strings);return  "/success.html";//默认当做内部转发处理  默认当做视图路径}@RequestMapping("/list.do")public String arr(Integer id,boolean flag,String name,@RequestParam("likes") List<String> likes){System.out.println("id: "+id);System.out.println("flag: "+flag);System.out.println("name: "+name);System.out.println(likes);return  "/success.html";//默认当做内部转发处理  默认当做视图路径}
}

2.2.3 页面代码

<html>
<head><title>Title</title>
</head>
<body>
<h1>简单的数据</h1>
<form action="param/simple.do" method="get"><p>ID:<input name="id"  /></p><p>boolean:<input name="flag" type="radio" value="true"  /><input name="flag" type="radio" value="false"  /></p><p>String:<input name="name"  /></p><p>city:<input name="City"  /></p><input type="submit" value="提交" />
</form>
<h1>对象的数据</h1>
<form action="param/obj.do" method="get"><p>ID:<input name="id"  /></p><p>boolean:<input name="flag" type="radio" value="true"  /><input name="flag" type="radio" value="false"  /></p><p>String:<input name="name"  /></p><input type="submit" value="提交" />
</form>
<h1>map的数据</h1>
<form action="param/map.do" method="get"><p>ID:<input name="id"  /></p><p>boolean:<input name="flag" type="radio" value="true"  /><input name="flag" type="radio" value="false"  /></p><p>String:<input name="name"  /></p><input type="submit" value="提交" />
</form>
<h1>数组的数据</h1>
<form action="param/arr.do" method="get"><p>ID:<input name="id"  /></p><p>boolean:<input name="flag" type="radio" value="true"  /><input name="flag" type="radio" value="false"  /></p><p>String:<input name="name"  /></p><p>likes:<input name="likes" type="checkbox" value="篮球"  />篮球<input name="likes" type="checkbox" value="足球"  />足球</p><input type="submit" value="提交" />
</form>
<h1>list的数据</h1>
<form action="param/list.do" method="get"><p>ID:<input name="id"  /></p><p>boolean:<input name="flag" type="radio" value="true"  /><input name="flag" type="radio" value="false"  /></p><p>String:<input name="name"  /></p><p>likes:<input name="likes" type="checkbox" value="篮球"  />篮球<input name="likes" type="checkbox" value="足球"  />足球</p><input type="submit" value="提交" />
</form>
</body>
</html>

2.3 SpringMVC的跳转

在SpringMVC中,默认的跳转方式内部转发,,每个URL前面默认有forward:

,默认会将方法的返回值当做视图的路径处理。并且,在SpringMVC中,/表示当前项目根目录。如果想要使用重定向,则使用关键字:redirect:/路径。

2.3.1 代码示例

package com.bjpowernode.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("jump")
public class JumpController {@RequestMapping("forward.do")public String forward(){System.out.println("内部转发跳转!");return  "forward:/success.html";}@RequestMapping("forward1.do")public String forward1(){System.out.println("内部转发跳转!");return  "/success.html";}@RequestMapping("redirect.do")public String redirect(){System.out.println("重定向跳转!");return  "redirect:/success.html";}
}

2.4 SpringMVC支持内置的对象

在SpringMVC中,支持为处理器中的方法注入内置的对象,如:HttpServletRequest、HttpServletResponse、HttpSession、Model等。

/**** @param request* @param resp* @param session* @param model  是springmvc中 推荐使用参数传递的容器 当参数发生覆盖 优先使用model中的参数* @throws IOException*/
@RequestMapping("servletParam.do")
public void servletParam(HttpServletRequest request, HttpServletResponse resp, HttpSession session, Model model) throws IOException {String name = request.getParameter("name");System.out.println(name);System.out.println(request);System.out.println(resp);System.out.println(session);System.out.println(model);resp.sendRedirect("success.html");//return "/success.html";
}

2.5 Spring+SpringMVC+Mybatis整合

2.5.1 创建项目导入jar包

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>02-mvc01</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><spring.version>5.2.0.RELEASE</spring.version>
</properties>
<dependencies><!--servlet-api--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency><!-- jsp-api --><dependency><groupId>javax.servlet.html</groupId><artifactId>jsp-api</artifactId><version>2.2</version></dependency><!-- jstl jar --><dependency><groupId>org.glassfish.web</groupId><artifactId>jstl-impl</artifactId><version>1.2</version></dependency><!-- spring相关jar --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><!-- spring相关jar 结束 --><!-- mysql 数据库 jar --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version></dependency><!-- mysql 数据库 end --><!-- mybatis 开始  --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><!-- mybatis  结束 --><!-- mybatis 和 spring的整合包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.4</version></dependency><!-- mybatis 和 spring的整合包  end --><!-- 日志 开始 --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.13.3</version></dependency><!-- 日志 结束 --><!--pagehelper分页--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.0</version></dependency><!-- 分页插件 结束 --><!-- lombok 开始 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!-- lombok 结束 -->
</dependencies><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource></resources>
</build></project>

2.5.2 定义相关类

2.5.2.1 domain

package com.bjpowernode.domain;import lombok.Data;
/*** @Description: 用户类*/
@Data
public class User {private Integer id;private String username;private String password;private String realname;
}

2.5.2.2 mapper

package com.bjpowernode.mapper;import com.bjpowernode.domain.User;import java.util.List;/*** @Description: 用户数据操作类*/
public interface UserMapper {/*** 查询所有 用户信息* @return*/List<User> selectAll();
}

2.5.2.3 service

package com.bjpowernode.service;import com.github.pagehelper.PageInfo;
import com.bjpowernode.domain.User;public interface IUserService {/***  分页查询数据* @param page* @param limit* @return*/PageInfo<User> queryPage(Integer page,Integer limit);
}package com.bjpowernode.service.impl;import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.bjpowernode.domain.User;
import com.bjpowernode.mapper.UserMapper;
import com.bjpowernode.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @Description: 用户业务实现类*/
@Service
public class UserServiceImpl implements IUserService {@Autowiredprivate UserMapper userMapper;/*** 分页查询数据* @param page* @param limit* @return*/@Overridepublic PageInfo<User> queryPage(Integer page, Integer limit) {Page<User> pageObj = PageHelper.startPage(page, limit);userMapper.selectAll();return pageObj.toPageInfo();}
}

2.5.2.4 controller

package com.bjpowernode.controller;import com.github.pagehelper.PageInfo;
import com.bjpowernode.domain.User;
import com.bjpowernode.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;/*** @Description: 用户控制类*/
@Controller
@RequestMapping("user")
public class UserController {@Autowiredprivate IUserService  userService;@RequestMapping("page.do")public ModelAndView page(@RequestParam(name = "page",required = false,defaultValue = "1") Integer page, @RequestParam(name = "limit",required = false,defaultValue = "10")  Integer limit){PageInfo<User> pageInfo = userService.queryPage(page, limit);ModelAndView modelAndView = new ModelAndView();//设置视图路径modelAndView.setViewName("/list.html");//设置数据modelAndView.addObject("pageInfo",pageInfo);return  modelAndView;}
}

2.5.2.5 页面

<html>
<head><title>Title</title>
</head>
<body><table ><thead><th>ID</th><th>username</th><th>password</th><th>realname</th></thead></table>
</body>
</html>

2.5.3 配置文件
2.5.3.1 数据库配置文件
#数据库连接信息
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/stmng?useUnicode=true&characterEncoding=utf8&useSSL=false
jdbc.username=root
jdbc.password=root
2.5.3.2 日志配置文件

# 全局日志配置
log4j.rootLogger=DEBUG, stdout
# MyBatis 日志配置
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2.5.3.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"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"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/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 整合mybatis --><!--1. 引入数据库配置文件  因为创建数据源  --><context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="FALLBACK" /><!--2. 创建数据源--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="${jdbc.driver}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean><!--3. 创建SqlSessionFactoryBean --><!-- configuration 指 mybatis的核心配制信息 --><bean id="configuration" class="org.apache.ibatis.session.Configuration"><property name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl"/><property name="cacheEnabled" value="true" /></bean><bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 数据源 --><property name="dataSource" ref="dataSource"/><!-- 使用 configuration 取代了  mybatis的核心配置文件--><property name="configuration" ref="configuration"/><!-- 配置mapper 映射 文件--><property name="mapperLocations" value="classpath:mapper/**Mapper.xml" /><!-- 配置类别名 --><property name="typeAliasesPackage" value="com.bjpowernode.domain" /><!-- 配制插件 --><property name="plugins"><array><!-- 分页插件 --><bean class="com.github.pagehelper.PageInterceptor" /></array></property></bean><!--4. Mapper接口的扫描 自动创建代理类 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!-- 被扫描的mapper接口  产生接口的实现类 对象 使用SqlSession.getMapper(接口.class) --><property name="basePackage" value="com.bjpowernode.mapper" /><!-- 注入一个SqlSessionFactoryBean  为了产生 SqlSession --><property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean" /></bean><!-- 5. 配置事务 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 指定被管理事务的数据源 --><property name="dataSource" ref="dataSource" /></bean><!-- 配置声明式事务  XML  注解 --><!-- 开启事务注解 --><tx:annotation-driven transaction-manager="transactionManager"  /><!-- 开启组件扫描 创建 对象 --><context:component-scan base-package="com.bjpowernode" />
</beans>

2.5.3.4 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"><!-- 开启组件扫描 --><!-- 扫描的目的是为了将 处理器放入到HandlerMapping中 --><context:component-scan base-package="com.bjpowernode.controller" /><!-- 开启springmvc注解 --><mvc:annotation-driven />
</beans>

2.5.3.5 Mapper配置文件

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

2.5.3.6 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><!-- 配置监听器需要加载的配置文件 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-context.xml</param-value></context-param><!-- 加载初始化spring核心配置文件配置监听器  启动时就加载 spring核心配置文件 IOC容器相关初始化--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 配置 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:springmvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
</web-app>

2.6 SpringMVC获取Servlet作用域

package com.bjpowernode.util;import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** @Description: 获取Servlet 作用域对象工具类*      HttpServletRequest*      HttpSession*      ServletContext*/
public class WebScopeUtil {/***  获取当前  HttpServletRequest 对象* @return*/public static HttpServletRequest getRequest(){ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();return  requestAttributes.getRequest();}/*** 获取当前请求绑定的session* @return*/public static HttpSession getSession(){return  getRequest().getSession();}/***  获取全局容器对象* @return*/public static ServletContext getContext(){//getRequest().getServletContext(); // ServletContext 的生命周期 是早于 HttpServletRequest//所以不能通过 HttpServletRequest 获取ServletContext  可能发生 NullpointExceptionreturn  ContextLoader.getCurrentWebApplicationContext().getServletContext();}
}

2.7 SpringMVC内置的编码过滤器

在springmvc中,为了解决乱码问题,springmvc提供了内置的编码过滤器。在使用时,只需要在web.xml中进行配置即可。

<!-- 编码过滤器 -->
<filter><filter-name>charsetFilter</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>charsetFilter</filter-name><!-- 只对springmvc处理的请求进行编码过滤 --><servlet-name>springmvc</servlet-name>
</filter-mapping>

2.8 SpringMVC返回JSON

{key1:value1,key2:value2}:key为String,value为Object
[{},{},{}…]

实体类对象、Map<String,Object>、List<实体类>、List<Map<String,Object>>

fastjson.jar: JSON.toJSONString(Object)

在springmvc中,默认返回的数据不论是什么格式,都当做视图进行解析。会根据返回值的toString的结果,当做路径去查找视图的模板,如果想要返回JSON,则需要使用注解,标识该方法返回的是JSON数据,不要当做视图路径进行路径的查找.该注解为:@ResponseBody.因为springmvc有内置的消息转换器,如果想要特殊设置,需要进行XML配置.

2.8.1 XML配置的形式
XML配置形式,是修改了默认结果处理,全局生效的。使用注解@ResponseBody,标识该方法返回的内容不是URL地址,而是一个消息,使用输出对象输出给客户端。

@RequestMapping

name : 方法映射名称

value/path : 方法访问路径

method : 支持的请求的方法类型:

GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE

params : 请求必须有的参数

headers : 请求必须有的头信息

consumes : 指定请求的数据格式类型 : 普通文本、表单格式、JSON

produces : 指定返回数据的格式类型 :JSON 、HTML

<!-- 配置JSON转换器 -->
<!--<bean id="config" class="com.alibaba.fastjson.support.config.FastJsonConfig">-->
<!--</bean>-->
<mvc:annotation-driven  ><mvc:message-converters register-defaults="true"><!--将内容转化为字符串消息  使用 IO发送给客户端此时只支持字符串--><!--<bean class="org.springframework.http.converter.StringHttpMessageConverter" />--><!-- 将内容转化为JSON字符串 发送客户端  能够处理对象--><!-- date  年--日 时:分:秒 --><bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter" /></mvc:message-converters>
</mvc:annotation-driven>

2.8.2 注解
SpringMVC中,有内置的转换器,但是SpringMVC内置的转换器需要相关jar包,需要jackson的jar包。只需要导入jar包后,使用@ResponseBody标识返回的数据是消息即可。SpringMVC自动将返回数据当做JSON字符串处理,并且消息按照UTF-8进行编码。如果@ResponseBody放在类上,类中所有的方法都返回的是消息,不是视图资源。

注意:

@RestController

是 @ResponseBody, @Controller 结合,标识该类是一个处理器,并且处理器中所有的方法都返回的是消息。

<!-- 导入jackson的jar包 -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.2</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.11.2</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.11.2</version>
</dependency>

2.9 文件上传下载

在springmvc中,也对文件上传进行了封装。更进一步的简化的文件上传,只需导入文件上传相关的jar包和处理文件上传的解析器即可。

2.9.1 文件上传
2.9.1.1 导入jar包

<!-- 文件上传相关依赖jar  -->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>

2.9.1.2 配置文件上传的解析器

在SpringMVC的核心配置文件中,新增文件上传解析器配置:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--文件格式编码--><property name="defaultEncoding" value="UTF-8"></property><!--配置单个文件上传大小:1M--><property name="maxUploadSizePerFile" value="1048576"></property><!--配置所有文件上传总大小:10M--><property name="maxUploadSize" value="10485760"></property></bean>

2.9.1.3 处理文件上传请求

页面

<html>
<head><title>文件上传</title>
</head>
<body>
<form action="file/upload2.do" method="post" enctype="multipart/form-data"><p>普通的文本数据:<input  name="name" type="text" /></p><p>文件数据:<input  name="userImg" type="file" /></p><p>文件数据:<input  name="userImg" type="file" /></p><input type="submit" value="提交">
</form>
</body>
</html>

处理器

package com.bjpowernode.controller;
import cn.hutool.core.img.Img;
import cn.hutool.core.img.ImgUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;@Controller
@RequestMapping("file")
public class FileUploadController {/***  如果是单个文件,则直接使用MultipartFile 对象进行接收*  普通的文本数据 则直接使用相应的类型进行接收*  如果名字不一致 @RequestParam 注解 处理名称* @param name* @param file* @return*/@RequestMapping("upload1.do")public String upload1(String name,@RequestParam("userImg") MultipartFile file){System.out.println("文本数据为:"+name);System.out.println("文件数据为:"+file.getName());//input name 属性值System.out.println("文件数据为:"+file.getSize()); // 文件的字节大小System.out.println("文件数据为:"+file.getOriginalFilename()); //文件的真实名称return "/success.html";}/***  如果是多个文件 则使用MultipartFile[] 数组进行接收* @param name* @param files* @return*/@RequestMapping("upload2.do")public String upload2(String name,@RequestParam("userImg") MultipartFile[] files){System.out.println("文本数据为:"+name);for (MultipartFile file : files) {System.out.println("文件数据为:"+file.getName());//input name 属性值System.out.println("文件数据为:"+file.getSize()); // 文件的字节大小System.out.println("文件数据为:"+file.getOriginalFilename()); //文件的真实名称//将文件进行保存File newFile = new File("d://"+file.getOriginalFilename());try {Font font = new Font("微软雅黑",Font.BOLD,15);ImgUtil.pressText(file.getInputStream(),new FileOutputStream(newFile),"我是水印", Color.RED,font,1,1,0.5f);//将文件保存在磁盘上//file.transferTo(newFile);} catch (IOException e) {e.printStackTrace();}}return "/success.html";}
}/*** 一个file控件同时上传多个* MultipartFile代表一个文件  MultipartRequest:封装了多个MultipartFile对象*/
@RequestMapping("/uploadMany2.do")
public void uploadMany2(MultipartRequest mr) throws IOException {List<MultipartFile> fileList = mr.getFiles("f");for (int i = 0;fileList!=null && i < fileList.size(); i++) {MultipartFile tempFile = fileList.get(i);//将上传的文件保存到D:\\uploads\\String name = tempFile.getOriginalFilename();//获取上传文件的名字 1.2.3.jpg 1.jpg  1.avi  C:\\users\\desktop\\1.jpg//获取上传文件的拓展名int index = name.lastIndexOf(".");String ext = name.substring(index);//.jpg .avi  .pptx//将上传的文件保存到指定目录String fileName = UUID.randomUUID().toString();File file = new File("D:\\uploads\\"+fileName+ext);tempFile.transferTo(file);}
}

2.9.2 文件下载

2.9.2.1 方案一(推荐):
文件下载的本质,就是获取服务器的文件数据信息,使用字节流将数据传递给客户端。

  1. 使用输入流,将磁盘文件读到内存中。

  2. 使用网络输出流,将数据输出给客户端。

package com.bjpowernode.controller;import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;/*** @Description: 文件下载示例*/
@Controller
@RequestMapping("download")
public class DownLoadController {/*** 文件下载的方法*/@RequestMapping("download.do")public  void download(HttpServletResponse response) throws Exception {File file = new File("E:\\猪图片.jpg");//本地磁盘文件//使用输入流  将文件读入内存中FileInputStream fis = new FileInputStream(file); // 找参照物   将程序运行的内存当做参照物byte[] b = new byte[1024];int len = -1;ServletOutputStream out = response.getOutputStream();//输出流  输出客户端//浏览器 默认打开了这个文件//设置响应类型 通知浏览器 不要打开response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);//文件的名称  不对//设置响应的文件的名称//如果响应的数据的名称是中文,在设置文件的名称时 要先将文件的名称进行编码 再进行传输String name = URLEncoder.encode("猪图片.jpg", "UTF-8");System.out.println("编码后的名字:"+name);response.setHeader("Content-Disposition", "attachment; filename="+name);//循环读  循环写while((len = fis.read(b)) != -1) {out.write(b,0,len);out.flush();}out.close();fis.close();}
}

2.9.2.2 方案二:

springMVC中为了简化文件的下载,封装了实体类:ResponseEntity,可以将文件数据封装在ResponseEntity中。

package com.bjpowernode.controller;import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;/*** @Description: 文件下载示例*/
@Controller
@RequestMapping("/download")
public class DownLoadController {@RequestMapping("/download2.do")public ResponseEntity<Byte[]> download() throws Exception {File file = new File("E:\\猪图片.jpg");//本地磁盘文件//使用输入流  将文件读入内存中FileInputStream fis = new FileInputStream(file); // 找参照物   将程序运行的内存当做参照物//文件的大小long length = file.length();//创建一个和文件一样大小的字节数组  一次性将数据读入到内存中  如果文件量过大,请求比较频繁 存在 崩溃的风险byte[] fileByte = new byte[(int) length];//一个G 的   byte 数组  64 G    65个人下载   1分钟//一次性将文件数据读入到数组中fis.read(fileByte);// springmvc 中封装的 响应实体 ://设置响应码//设置响应的数据头信息//设置响应数据HttpHeaders headers = new HttpHeaders(); //响应头信息//设置响应的数据为流数据  告诉浏览器 不要解析headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//设置下载的文件的名称  中文字符串要进行编码headers.setContentDispositionFormData("filename","猪图片.jpg");ResponseEntity responseEntity = new ResponseEntity(fileByte,headers, HttpStatus.OK);return responseEntity;}
}

2.10 SpringMVC中的拦截器

SpringMVC提供HandlerInteceptor接口,这个接口用于拦截处理具体的Handler中的方法,在具体的Handler中的方法执行前后及返回视图之间都可以进行相关扩展操作。

2.10.1 如何使用拦截器
2.10.1.1 创建类实现HandlerInteceptor接口

package com.bjpowernode.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @Description: 自定义拦截器*/
public class MyInterceptor implements HandlerInterceptor {/*** 在执行具体的Handler中的方法前执行* @param request  当前的请求对象* @param response  当前的响应对象* @param handler   具体的处理器中将要执行的方法* @return   boolean  如果 返回 true 则执行Handler中的方法   false 则 不执行handler中的方法* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("我是拦截器中preHandle 方法");return true;}/***  在具体的Handler中的方法执行完成 但是没有做具体的视图解析操作* @param request  当前 请求对象* @param response  当前响应对象* @param handler 具体的处理器中将要执行的方法* @param modelAndView 具体的处理器中将要执行的方法 返回的结果* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("我是拦截器中postHandle 方法");//在具体的解析之前  修改视图模型中数据modelAndView.addObject("name","韩梅梅");}/***  完成了视图解析后 整个方法执行完成调用的方法 在finally中调用 或者出现异常也会调用* @param request   当前请求对象* @param response  当前响应对象* @param handler   具体的处理器中将要执行的方法* @param ex         具体的处理器中抛出的异常* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("我是拦截器中afterCompletion 方法");System.out.println(ex.getMessage());request.setAttribute("msg","网管去火星了!");request.getRequestDispatcher("/500.html").forward(request,response);}
}

2.10.1.2 配置拦截器

<?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.bjpowernode.controller" /><!-- 开启 mvc注解 --><mvc:annotation-driven></mvc:annotation-driven><!-- 文件上传的解析器 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" ><!--<property name="maxUploadSize" value="1"></property>--></bean><!-- 配置springmvc的拦截器 --><mvc:interceptors><mvc:interceptor><!-- 拦截器的资源路径  /** 拦截所有  ** 表示多层目录 --><mvc:mapping path="/**"/><!-- 不拦截的资源路径 --><mvc:exclude-mapping path="/user/page.do"/><!-- 自定义的拦截器 --><bean id="myInterceptor" class="com.bjpowernode.interceptor.MyInterceptor" /></mvc:interceptor></mvc:interceptors>
</beans>

注意:

  1. 在拦截器中,最先执行preHandle,然后执行Handler中具体的方法,再然后执行postHandle和afterCompletion。preHandle就是前置的拦截的方法,返回如果为true,则执行处理器中的方法,如果为false则不执行处理器中的方法。postHandle是在Handler中具体的方法执行完成,但是没有交给视图解析器之前执行,afterCompletion在视图解析器完成了视图解析之后执行的。

  2. 拦截器是拦截器的方法,被DispatcherServlet代理调用的方法,如果请求的不是Handler,拦截器是不会拦截的。index.html由于是由tomcat默认的servlet进行返回的,不会执行DispatcherServlet中的doDispatch,那么拦截器无法进行拦截。

2.10.2 Interceptor和Filter的区别
Filter是Java Web的规范,拦截的是请求,任何JavaWeb项目都可以有Filter,但是Interceptor是SpringMVC提供的一套规范HandlerInterceptor,只适用SpringMVC自身,并且只能对DispatherServlet处理器的请求生效,拦截的方法。从范围上说,任何JavaWeb项目都有Filter,但是未必有Interceptor。

1、filter可以应用于任何的javaweb项目;inteceptor应用于springmvc框架

2、Filter可以过滤所有请求资源(不限于html、css、js、images等);Interceptor只能拦截所有的controller方法

3、Filter过滤路径时,没有排除选项;Interceptor可以排除拦截路径

2.11 异常处理器

在spring中,相对完善的异常处理器机制,spring可以自己定义处理异常的规则,这种处理异常规则的程序,就被称之为异常处理器。其实,异常处理器就是对controller的增强,因为异常是向上抛,controller调用service,service调用mapper,controller属于最上层,所以最终异常都会汇集到controller。因此,spring提供了@ControllerAdvice注解,表示对controller增强类。并且还提供了@ExceptionHandler这个注解,当发生异常时,该注解修饰的方法就会执行。

在实际开发中,异常主要分为两类:

  1. 系统异常,JDK中定义的异常

  2. 业务异常,开发者自己定义的异常

一般是将系统异常转化为业务异常,开发者只处理业务异常。使用try…catch…将代码包裹起来,在catch中抛出自定义的异常,这种方案就是将系统异常转化为业务异常。因为很多数据操作,事务需要异常进行数据回滚。

package com.bjpowernode.handler;import com.bjpowernode.exception.BussiException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;/*** @Description: 全局异常处理器*/
@ControllerAdvice
public class GlobalExceptionHandler {/***  具体的异常处理方法* @param exception*/@ExceptionHandlerpublic void doException(Exception exception){//exception  FileNotFound indexOutof  xxxx//判断 异常类型是不是自定义异常if (exception instanceof BussiException){BussiException ex = (BussiException) exception;Integer code = ex.getCode();//获取异常码String msg = ex.getMsg();//获取异常消息System.out.println(code +":"+msg);//Result  转化为JSON字符串   将JSON字符串返回给客户端}}
}package com.bjpowernode.exception;/*** @Description: 自定义异常*/
public class BussiException extends RuntimeException {private Integer code;//异常码private String msg;//异常消息public BussiException(){}public BussiException(Integer code,String msg){super(msg);this.code = code;this.msg = msg;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}package com.bjpowernode.controller;import com.bjpowernode.exception.BussiException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping("/test")
public class TestController {@RequestMapping("/test.do")public String test(){//数据校验  可能发生的情况  很多种int m = 0;try {System.out.println(100/m);}catch (Exception e){e.printStackTrace();//打印异常//自己抛出了异常throw  new BussiException(1001,"被除数不能为0");}return  "/success.html";}
}

2.12 springmvc中数据校验

springmvc中的数据校验时通过hibernate-validator实现,对实体类中的字符串有效。

1、引入hibernate-validator依赖

2、在实体类中的字符串(正则表达式)属性上添加相关注解

3、可以用hibernate-validor提供的特有注解对Long、Integer、Float做校验

4、在被校验的实体类前添加@Valid注解

5、当实体类中的数据格式发生错误时,错误信息被封装到了BindResult对象中去,BindResult必须和实体类紧紧挨在一起

2.13 Restful风格

Restful风格适合参数少、参数不敏感的请求地址。使用了restful风格的请求地址,就不能使用.do的方式请求

Resustful风格:

  1. 请求地址问题

  2. 请求方式问题

http://localhost:8080/getBooksByFenye.do?pageNum=1&pageSize=5

http://localhost:8080/getBooksByFenye/1/5

2.13.1 Http协议设计的初衷
HTTP协议在设计时,期望使用一个URL表示一个资源。然后,根据不同的动作:GET、POST、PUT、DELETE等等表示对一个资源的各种操作。

如:

获取这个资源就使用GET, @GetMapping(“/”)

修改这个资源PUT, @PutMapping()

删除这个资源用DELETE,@DeleteMapping()

创建这个资源使用POST。 @PostMapping()

但是在实际使用中,多个URL表示一个资源,例如:新增用户: addUser.do,修改用户:updateUser.do,删除用户:deleteUser.do,查询一个用户:getUser.do。这时候,出现一个资源存在多个URL。在一定程度声,违背了HTTP协议的设计初衷,并且命名也是个问题。

2.13.2 Restful设计思想

  1. 使用一个URL表示一种资源

  2. 客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源

  3. 通过操作资源的表现形式来操作资源

2.13.3 在SpringMVC中使用Restful
SpringMVC也支持Restful风格,但是目前存在一些问题。主要不是很好支持PUT请求,没有办法获取到PUT请求的数据。

2.13.3.1 将DispatherServlet的映射地址改为
由于将DispatherServlet的映射路径,改为了/,则所有的请求都由DispatherServlet处理,静态的资源文件不在处理器映射器中,会出现404。并拦截器拦截DispatherServlet中调用Handler中的方法,改为/,则所有的请求都会被拦截。

则需要在SpringMVC的核心配置文件中,新增启用默认的Servlet的处理器。

<!-- 启用默认Servlet -->
<mvc:default-servlet-handler/>

并且注意,配置拦截器时,将静态资源不进行拦截,要排除:

<mvc:exclude-mapping path="/resouces/**"/>

2.13.3.2 配置处理PUT请求的拦截器

<!-- 处理put请求的拦截器 -->
<filter><filter-name>restful</filter-name><filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping><filter-name>restful</filter-name><servlet-name>springmvc</servlet-name>
</filter-mapping>

2.13.3.3 处理器代码

package com.bjpowernode.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;@RestController
@RequestMapping("user")
public class UserController {//    @RequestMapping(method = RequestMethod.GET)
//    //@GetMapping
//    public Object get(Integer id){
//        System.out.println("get请求");
//        Map<String,Object> data = new HashMap<>();
//        data.put("code",200);
//        data.put("msg","get请求");
//        return  data;
//    }@GetMapping("{id}/{name}") //后台的获取方式 使用 {} 进行包裹  并且 在方法参数中 使用@PathVariable// 这种将参数拼接在URL上的方式 只支持 GET 请求和 DELETE请求public Object get1(@PathVariable("id") Integer id,@PathVariable("name") String name){System.out.println("get请求");System.out.println(id);System.out.println(name);Map<String,Object> data = new HashMap<>();data.put("code",200);data.put("msg","get请求");return  data;}//@RequestMapping(method = RequestMethod.PUT)@PutMappingpublic Object put(Integer id){System.out.println("PUT请求");Map<String,Object> data = new HashMap<>();data.put("code",200);data.put("msg","PUT请求");return  data;}@RequestMapping(method = RequestMethod.POST)@PostMappingpublic Object post(Integer id){System.out.println("post请求");Map<String,Object> data = new HashMap<>();data.put("code",200);data.put("msg","post请求");return  data;}//@RequestMapping(method = RequestMethod.DELETE)@DeleteMappingpublic Object delete(Integer id){System.out.println("delete请求");Map<String,Object> data = new HashMap<>();data.put("code",200);data.put("msg","delete请求");return  data;}
}

2.13.3.4 页面代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><button id="btn1">get</button><button id="btn2">put</button><button id="btn3">delete</button><button id="btn4">post</button><button id="btn5">get-1111</button><script src="resources/jquery.js"></script><script>$("#btn1").click(function () {$.get("user",{id:1001},function (rs) {console.log(rs);})});$("#btn2").click(function () {$.ajax({url:"user",type:"PUT",data:{id:1001},success:function (rs) {console.log(rs);}})});$("#btn3").click(function () {$.ajax({url:"user",type:"DELETE",data:{id:1001},success:function (rs) {console.log(rs);}})});$("#btn4").click(function () {$.post("user",{id:1001},function (rs) {console.log(rs);})});$("#btn5").click(function () {//将参数 拼接在URL上面$.get("user/11111/lucy",function (rs) {console.log(rs);})});</script>
</body>
</html> 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIP---MPLS---LDP

文章目录 目录 文章目录 前言 一.LDP基本工作机制 LDP工作原理概述 LDP对等体&#xff1a; 二.本地LDP会话自动建立过程 三.LDP优化 PHP机制&#xff1a; 四.LDP配置 总结 前言 MPLS 基于标签转发表进行转发&#xff0c;与路由表类似&#xff0c;标签转发表有两种获取渠道&a…

【Rust】快速教程——自定义类型、数字转枚举、Cargo运行

前言 超过一定的年龄之后&#xff0c;所谓人生&#xff0c;无非是一个不断丧失的过程而已。宝贵的东西&#xff0c;会像梳子豁了齿一样从手中滑落下去。你所爱的人会一个接着一个&#xff0c;从身旁悄然消逝。——《1Q84》 \;\\\;\\\; 目录 前言自定义类型数字转枚举Cargo.tom…

【LeetCode刷题-链表】--86.分隔链表

86.分隔链表 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }* }*/ class…

前端学习--React(3)

一、Redux 集中状态管理工具&#xff0c;不需要react即可使用&#xff0c;每个store的数据都是独立于组件之外的 vue小链接&#xff1a;vuex/pinia 基本使用 Redux将数据修改流程分成三个概念&#xff0c;state、action和reducer state - 一个对象 存放我们管理的数据状态 a…

某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】

文章目录 前言js实现push方法js实现订阅发布手写防抖节流手写reduce方法深拷贝es5去重数组多维数组去重排序简单递归实现树形结构输出遍历后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端面试 &#x1f431;‍&#x1f453;博主在前…

Linux僵死进程及文件操作

1.僵死进程(僵尸进程)&#xff1a; 1.僵死进程产生的原因或者条件: 什么是僵死进程? 当子进程先于父进程结束,父进程没有获取子进程的退出码,此时子进程变成僵死进程. 简而言之,就是子进程先结束,并且父进程没有获取它的退出码; 那么僵死进程产生的原因或者条件就是:子进…

直接插入排序和希尔排序

前言 我们前面几期介绍了线性和非线性的基本数据结构。例如顺序表、链表、栈和队列、二叉树等~&#xff01;本期和接下来的几期我们来详解介绍各个排序的概念、实现以及性能分析&#xff01; 本期内容 排序的概念以及其运用 常见的排序算法 直接插入排序 希尔排序 一、排序的…

vue2项目从0搭建(三):配置环境变量及对应的webpack配置

前言 实际业务开发中,一个项目很可能会同时配置好几套环境。 比如:常规开发环境,开发测试环境,正式的测试环境,预发测试环境,客户甲的生产环境,客户乙的生产环境,通用生产环境,独立应用环境,微前端环境,大屏专用环境,移动端环境。 一女多嫁的实际业务场景,就需要我们进行多样…

安卓用SQLite数据库存储数据

什么是SQLite&#xff1f; SQLite是安卓中的轻量级内置数据库&#xff0c;不需要设置用户名和密码就可以使用。资源占用较少&#xff0c;运算速度也比较快。 SQLite支持&#xff1a;null&#xff08;空&#xff09;、integer&#xff08;整形&#xff09;、real&#xff08;小…

第29期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

Linux篇:文件系统

一、共识原理&#xff1a; 文件文件内容文件属性 磁盘上存储文件存文件的内容&#xff08;数据块&#xff09;存文件的属性&#xff08;inode&#xff09; Linux的文件在磁盘中存储是将属性和内容分开存储的。 二、硬件简述&#xff1a; 1. 认识硬件 磁盘&#xff1a;唯一的一…

混合云案例:利用 Databend Cloud 高效加速私有 Databend 的策略与实施

背景 Databend 是一款基于对象存储的存算分离湖仓产品&#xff0c;已成为云上大数据分析中高效且低成本的首选解决方案。目前&#xff0c;Databend 在多个用户场景中得到广泛应用&#xff0c;包括&#xff1a; 新媒体行业数据分析及大屏数据展示云上 CDH 替代以减少本地磁盘和…

Deep Image Prior

深度图像先验 论文链接&#xff1a;https://sites.skoltech.ru/app/data/uploads/sites/25/2018/04/deep_image_prior.pdf 项目链接&#xff1a;https://github.com/DmitryUlyanov/deep-image-prior Abstract 深度卷积网络已经成为一种流行的图像生成和恢复工具。一般来说&a…

web:[ZJCTF 2019]NiZhuanSiWei1

题目 点进题目&#xff0c;网页显示如下&#xff0c;需要代码审计 $_GET["text"]和$_GET["file"]来获取传入的两个参数text和file。使用isset()函数来检查$text变量是否已设置并且不为null。如果设置了并且不为null&#xff0c;则执行下面的逻辑。在下面的…

汽车电子 -- 车载ADAS之LCA(变道辅助系统)

相关法规文件: LCA: ISO 17387-2008 Intelligent transport systems — Lane change decision aid systems 一、变道辅助系统 LCA &#xff08;Lane Change Assist&#xff09; LCA 系统&#xff08;变道辅助系统&#xff09;监测后方相邻车道区域&#xff0c;如果有车辆在后…

《融合SCADA系统数据的天然气管道泄漏多源感知技术研究》误报数据识别模型开发

数据处理不作表述。因为我用的是处理后的数据&#xff0c;数据点这。 文章目录 工作内容1CC040VFD电流VFD转速压缩机转速反馈进出口差压 紧急截断阀开到位进出电动阀开到位发球筒电筒阀开到位收球筒电动阀开到位电动阀2005开到位越站阀开到位 工作内容2工作内容3 工作内容1 任…

Java小游戏 王者荣耀

GameFrame类 所需图片&#xff1a; package 王者荣耀;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayLis…

<JavaDS> 二叉树遍历各种遍历方式的代码实现 -- 前序、中序、后序、层序遍历

目录 有以下二叉树&#xff1a; 一、递归 1.1 前序遍历-递归 1.2 中序遍历-递归 1.3 后序遍历-递归 二、递归--使用链表 2.1 前序遍历-递归-返回链表 2.2 中序遍历-递归-返回链表 2.3 后序遍历-递归-返回链表 三、迭代--使用栈 3.1 前序遍历-迭代-使用栈 3.2 中序遍…

【Python3】【力扣题】367. 有效的完全平方数

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;Python函数。num的平方根 或者 num的0.5次幂。 知识点&#xff1a;float.is_integer(...)&#xff1a;判断浮点数的值是否等于整数。也可以&#xff1a;浮点数.is_integer()。 pow(a,b)&…

【SpringCloud】微服务的扩展性及其与 SOA 的区别

一、微服务的扩展性 由上一篇文章&#xff08;没看过的可点击传送阅读&#xff09;可知&#xff0c; 微服务具有极强的可扩展性&#xff0c;这些扩展性包含以下几个方面&#xff1a; 性能可扩展&#xff1a;性能无法完全实现线性扩展&#xff0c;但要尽量使用具有并发性和异步…