SpringMVC系列之技术点定向爆破二

SpringMVC的运行流程

图片

  • 客户端发送请求

  • tomcat接收对应的请求

  • SpringMVC的核心调度器DispatcherServlet接收到所有请求

  • 请求地址与@RequestMapping注解进行匹配,定位到具体的类和具体的处理方法(封装在Handler中)

  • 核心调度器找到Handler后交给HandlerAdapter执行具体的Handler

  • 执行后Controller将具体的执行结果(ModelAndView)返回给HandlerAdapter

  • 核心调度器把ModelAndView交给视图解析器,视图解析器找到具体的jsp封装到View对象中

  • View视图把jsp转换成html内容再交给核心调度器

  • 核心调度器把html内容返回给客户端。

RequestMapping注解

在Controller中通过RequestMapping注解来定义匹配请求的URL。

  • RequestMapping注解可以定义在类的上方,作为类的中多个方法的统一URL前缀。

  • RequestMapping注解定义在方法的上方,作为此次请求具体要执行的方法的限定。

/**
@Author: 索尔
*/
@Controller //声明这是一个控制器
@RequestMapping("/hello") //访问路径,等价于url-pattern
public class HelloController {@RequestMapping("/test1") //访问路径public String hello1(){System.out.println("hello world");//具体的业务逻辑return "redirect:/index.jsp"; //跳转:/index.jsp}
}

RequestParam注解

RequestParam注解往往和RequestMapping注解配合使用,用来绑定请求参数和处理方法的参数。

我们来看下RequestParam注解的源码:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {@AliasFor("name")String value() default "";@AliasFor("value")String name() default "";boolean required() default true;String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
  • @RequestParam(required = false/true,value = “参数名”,defaultValue = “”) 其中name和value等效这里用value,推荐使用value。

  • value:用于重命名参数,若使用了value,则前端请求时该参数必须与value相同

  • required:用来制定该参数是否必须传入

    • true:默认值,前端请求时默认必须传入

    • false:前端请求时可以不传,不传时后端收到的是null

  • defaultValue:如果设置了defaultValue,则required不会使用默认值true,而自动为false。当没有穿参数时,就使用默认值。

接收复杂类型的参数

  • 设计User类,包含了多种复杂类型。

/**
@Author: 索尔
*/
public class User {private int id;private String name;private String[] hobbies;private Address address;private List<String> schools;private List<User> family;private Map<String,String> scores;...
}
  • 设计Controller的处理方法,接收复杂类型的参数并打印

 /*** 接收复杂类型的参数* @return*/@RequestMapping("/test3")public String test3(User user){System.out.println(user);return "redirect:/index.jsp";}

使用SpringMVC直接接收来自jsp发起的Get或着Post请求。

  • 设计存放表单的jsp页面


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><form action="${pageContext.request.contextPath}/demo/test3" method="post">id:<input type="text" name="id"> <br/>姓名:<input type="text" name="name"><br/>爱好:<input type="checkbox" name="hobbies" value="阅读">阅读</input><input type="checkbox" name="hobbies" value="看片">看片</input><input type="checkbox" name="hobbies" value="音乐">音乐</input><br/>所在城市:<input type="text" name="address.city">所在街道:<input type="text" name="address.street"><br/>毕业院校:<input type="text" name="schools[0]"><input type="text" name="schools[1]"><br/>家庭成员:父亲:<input type="text" name="family[0].name">母亲:<input type="text" name="family[1].name"><br/>成绩:计算机:<input type="text" name="scores['计算机']">大学英语:<input type="text" name="scores['大学英语']"><br/><input type="submit" value="注册"/></form>
</body>
</html>

注意List、Map、实体类中的实体类的参数命名方式。当填入表单数据后,程序可以收到指定类型的参数。

  • 页面设定的参数内容:

图片

  • 后端接收到的结果:

User{id=1010, name='小王', address=Address{city='杭州', street='上城'}, hobbies=[读书, 看片], schools=[北京大学, 清华大学], family=[User{id=0, name='张三', address=null, hobbies=null, schools=null, family=null, scores=null}, User{id=0, name='李四', address=null, hobbies=null, schools=null, family=null, scores=null}], scores={大学英语=100, 计算机=90}}

解决Post请求参数中文乱码问题

如果参数中包含中文,则会出现乱码问题。使用过滤器解决Post请求参数中文乱码问题。

web.xml文件中配置过滤器:

<!--编码过滤器,解决乱码问题--><filter><filter-name>characterFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!--设置编码格式为utf8--><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param><!--对request请求进行编码--><init-param><param-name>forceRequestEncoding</param-name><param-value>true</param-value></init-param><!--对response响应进行编码--><init-param><param-name>foreResponseEncoding</param-name><param-value>true</param-value></init-param></filter><!--配置要过滤的servlet--><filter-mapping><filter-name>characterFilter</filter-name><servlet-name>mvc</servlet-name></filter-mapping>

获得请求头数据

在JavaWeb中,需要繁琐的操作才能获得请求头数据。SpringMVC提供了快速获得请求头数据的方法。

@RequestMapping("/getHeader")public String getHeader(@RequestHeader("User-agent") String userAgent){System.out.println(userAgent);return "redirect:/index.jsp";}

获取Cookie数据

同样的,JavaWeb获得Cookie的方式也非常繁琐。SpringMVC提供了@CookieValue来快速获得Cookie中的数据。

 @RequestMapping("/getCookie")public String getCookie(@CookieValue("JSESSIONID") String jsessionid){System.out.println(jsessionid);return "redirect:/index.jsp";}

访问静态资源

在springmvc中,所有的请求都会被SpringMVC的核心处理器DispatcherServlet来处理,对于静态资源的请求也不例外。因此,需要告知SpringMVC,对于静态资源的请求不要去做处理,而是直接响应静态资源即可。通过springmvc的配置,完成静态资源的放行。

<!--配置访问静态资源--><mvc:annotation-driven/><!--将url中的路径映射到指定的资源文件夹--><mvc:resources mapping="/images/**" location="/images/" />

另一种处理静态资源的方法:DispatcherServlet处理不了,则交给DefaultServlet处理。

 <!--配置访问静态资源--><mvc:annotation-driven/><!--另一种处理静态资源的方法:DispatcherServlet处理不了,则交给DefaultServlet处理--><mvc:default-servlet-handler />

配置视图解析器

为了返回指定的视图,需要告知视图解析器如何获取指定视图。

<!-- 视图解析器作用:1.捕获后端控制器的返回值="index"2.解析:在返回值的前后 拼接 ==> "/index.jsp"--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 前缀 --><property name="prefix" value="/"></property><!-- 后缀 --><property name="suffix" value=".jsp"></property></bean>

文件下载

文件上传和下载是处理复杂数据类型的另一种方式。首先我们来看下如何实现文件的下载。

文件下载的核心逻辑是通过封装响应消息,将下载内容发送给客户端。

@RequestMapping("/download")public ResponseEntity<byte[]> download(HttpServletRequest request) throws Exception {//设置下载文件信息ServletContext context = request.getServletContext();String realPath = context.getRealPath("/images/img.jpeg");//创建输入流FileInputStream fis = new FileInputStream(realPath);byte[] bytes = new byte[fis.available()];//读取文件内容,存入到字节数组中fis.read(bytes);fis.close();//封装下载内容到响应消息中HttpHeaders headers = new HttpHeaders();headers.set("Content-Disposition","attachment;filename=imp.jpeg");return new ResponseEntity<byte[]>(bytes,headers, HttpStatus.OK);}

文件上传

文件上传的核心逻辑是读到客户端传递来的字节数据,再通过Java程序存入到指定位置。

文件上传需要引入第三方组件Commons-fileupload的支持。

<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency>
  • 编写上传界面

<body><form enctype="multipart/form-data" action="${pageContext.request.contextPath}/upload" method="post">文件:<input type="file" name="uploadFile" /><br/><input type="submit" value="上传"></form>
</body>
  • 在spring中注册上传组件

<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"><property name="defaultEncoding" value="UTF-8"></property><property name="maxUploadSize" value="#{1024
*1024*
16}"></property></bean>
  • 编写后端上传接口

 @PostMapping("/upload")public String upload(MultipartFile uploadFile) throws IOException {System.out.println(uploadFile.getOriginalFilename());String path = "/Users/zeleishi/Documents/code/springmvc-demo1/out/upload/"+uploadFile.getOriginalFilename();File file = new File(path);uploadFile.transferTo(file);return "success";}

总结

这一篇文章我们攻克了SpringMVC部分关键技术,建议小伙伴同时收藏SpringMVC系列三篇博文,攻克SpringMVC将变得轻而易举。

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

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

相关文章

【Java 基础】33 JDBC

文章目录 1. 数据库连接1&#xff09;加载驱动2&#xff09;建立连接 2. 常见操作1&#xff09;创建表2&#xff09;插入数据3&#xff09;查询数据4&#xff09;使用 PreparedStatement5&#xff09;事务管理 3. 注意事项总结 Java Database Connectivity&#xff08;JDBC&…

rqt_graph使用说明

其中右边的&#xff1a;/rosout是一个topic 也就是一个话题 /rosout是一个topic 也是一个话题 可以看到凡是在rqt_graph里面用长方形标识的全都是话题 通过观察可以发现&#xff1a;凡是用椭圆标识的全都是节点 如果切换为Nodes only视图会发现&#xff1a; 所说的no…

Java 中的内部类的定义

目录 一、成员内部类 二、静态内部类 三、局部内部类 四、匿名内部类 一、成员内部类 public class InnerClass {String name;private Integer age;static String hobby;/*** 成员内部类* 1、成员内部类中只能定义非静态属性和方法* 2、成员内部类中可以访问外部类的成员&a…

十一.约束(一)

约束 1.约束(constraint)概念1.1为什么需要约束1.2什么是约束1.3约束的分类 2.非空约束2.1作用2.2关键字2.3特点2.4添加非空约束2.5删除非空约束 3.唯一性约束3.1作用3.2关键字3.3特点3.4添加唯一约束3.5关于复合唯一约束3.5删除唯一约束 4.PRIMARY KEY 约束4.1作用4.2关键字4.…

数据分析基础之《numpy(5)—合并与分割》

了解即可&#xff0c;用panads 一、作用 实现数据的切分和合并&#xff0c;将数据进行切分合并处理 二、合并 1、numpy.hstack 水平拼接 # hstack 水平拼接 a np.array((1,2,3)) b np.array((2,3,4)) np.hstack((a, b))a np.array([[1], [2], [3]]) b np.array([[2], […

循环渲染ForEach

目录 1、接口说明 2、键值生成规则 3、组件创建规则 3.1、首次渲染 3.2、非首次渲染 4、使用场景 4.1、数据源不变 4.2、数据源组项发生变化 4.3、数据源数组项子属性变化 5、反例 5.1、渲染结果非预期 5.2、渲染性能降低 Android开发中我们有ListView组件、GridVi…

Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580

Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 Apache ShenYu 网关JWT认证绕过漏洞 CVE-2021-37580 已亲自复现) 漏洞名称 漏洞描述 Apache ShenYu是一个异步的&#xff0c;高性能的&#x…

Qt中字符串转换为JS的函数执行

简介 在 QML 中&#xff0c;将 JavaScript 字符串转换为函数通常涉及使用 Function 构造函数或 eval() 函数。但是&#xff0c;QML 的环境对 JavaScript 的支持有一定的限制&#xff0c;因此不是所有的 JavaScript 功能都可以在 QML 中直接使用。 以下介绍都是在Qt5.12.1…

Mybatis3系列课程8-带参数查询

简介 上节课内容中讲解了查询全部, 不需要带条件查, 这节我们讲讲 带条件查询 目标 1. 带一个条件查询-基本数据类型 2.带两个条件查询-连个基本数据类型 3.带一个对象类型查询 为了实现目标, 我们要实现 按照主键 查询某个学生信息, 按照姓名和年级编号查询学生信息 按照学生…

【【迭代七次的CORDIC算法-Verilog实现】】

迭代七次的CORDIC算法-Verilog实现求解正弦余弦函数 COEDIC.v module CORDIC #(parameter DATA_WIDTH 4d8 , // we set data widthparameter PIPELINE 4d8)(input clk ,input …

Jmeter关联操作

1.首先右键添加一个线程选择线程组,命名为线程组-1&#xff0c;添加取样器选择HTTP请求--城市天气 2.线程组-1右键&#xff0c;添加取样器选择后置处理器中的JSON提取器 3.线程组-1右键,添加取样器选择后置处理器中的BeanShell 后置处理程序(必须平级) 4.首先右键添加一个线程选…

[C++ 从入门到精通] 17.基类与派生类关系的详细再探讨

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…

微电网优化(Matlab复现)— 微电网两阶段鲁棒优化经济调度方法_刘一欣

论文链接&#xff1a;微电网两阶段鲁棒优化经济调度方法 - 中国知网 代码链接&#xff1a;https://m.tb.cn/h.5Mg7fCo?tkhnpmWgZiv2R 复现效果&#xff1a; 运行环境&#xff1a;Matlab 2020bCplexyalmip 1 微电网结构 图 1 所示为典型的微电网结构&#xff0c;由可控分布式…

如何在Portainer部署一个web站点到Nginx容器并结合内网穿透远程访问

文章目录 前言1. 安装Portainer1.1 访问Portainer Web界面 2. 使用Portainer创建Nginx容器3. 将Web静态站点实现公网访问4. 配置Web站点公网访问地址4.1公网访问Web站点 5. 固定Web静态站点公网地址6. 固定公网地址访问Web静态站点 前言 Portainer是一个开源的Docker轻量级可视…

基于Vite+Vue3 给项目引入Axios

基于ViteVue3 给项目引入Axios,方便与后端进行通信。 系列文章指路&#x1f449; 系列文章-基于Vue3创建前端项目并引入、配置常用的库和工具类 文章目录 安装依赖新建src/config/config.js 用于存放常用配置进行简单封装解决跨域问题调用尝试 安装依赖 npm install axios …

单元测试(超详细整理)

前言 为什么我们需要测试&#xff1f; 让产品可以快速迭代&#xff0c;同时还能保持高质量 对于一些相对稳定的系统级别页面&#xff0c;自动化测试在提高测试的效率的方面起到非常重要的作用。前端的自动化测试主要包括&#xff1a;浏览器测试和单元测试。Vue官方脚手架自带…

Python Opencv实践 - 手势音量控制

本文基于前面的手部跟踪功能做一个手势音量控制功能&#xff0c;代码用到了前面手部跟踪封装的HandDetector.这篇文章在这里&#xff1a; Python Opencv实践 - 手部跟踪-CSDN博客文章浏览阅读626次&#xff0c;点赞11次&#xff0c;收藏7次。使用mediapipe库做手部的实时跟踪&…

2024年【广东省安全员A证第四批(主要负责人)】考试内容及广东省安全员A证第四批(主要负责人)复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 广东省安全员A证第四批&#xff08;主要负责人&#xff09;考试内容是安全生产模拟考试一点通总题库中生成的一套广东省安全员A证第四批&#xff08;主要负责人&#xff09;复审考试&#xff0c;安全生产模拟考试一点…

二叉树的中序遍历(三种方法)

题目&#xff1a; 原题链接 简述题目就是&#xff1a;给你一颗二叉树的根结点root返回它的中序遍历 方法一&#xff08;递归&#xff09;&#xff1a; 中序遍历&#xff1a; 简单来说就是按照访问左子树——根节点——右子树的方式遍历这棵树&#xff0c;而在访问左子树或者右…

【基础知识】大数据组件HBase简述

HBase是一个开源的、面向列&#xff08;Column-Oriented&#xff09;、适合存储海量非结构化数据或半结构化数据的、具备高可靠性、高性能、可灵活扩展伸缩的、支持实时数据读写的分布式存储系统。 只是面向列&#xff0c;不是列式存储 mysql vs hbase vs clickhouse HMaster …