SpringMVC中的网络安全知识

网友投稿 266 2022-10-03


SpringMVC中的网络安全知识

Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet。

Spring MVC 是结构最清晰的 Servlet+JSP+JavaBean 的实现,是一个典型的教科书式的 MVC 构架,不像 Struts 等其它框架都是变种或者不是完全基于 MVC 系统的框架。

Spring MVC配置

Spring MVC 是基于 Servlet 的,DispatcherServlet 是整个 Spring MVC 框架的核心,主要负责截获请求并将其分派给相应的处理器处理。所以配置 Spring MVC,首先要定义 DispatcherServlet。跟所有 Servlet 一样,用户必须在 ​web.xml 中​进行配置。

​1)定义DispatcherServlet​

在开发 Spring MVC 应用时需要在 web.xml 中部署 DispatcherServlet,代码如下:

springMVC springmvc org.springframework.web.servlet.DispatcherServlet 1 springmvc /

Spring MVC 初始化时将在应用程序的 WEB-INF 目录下查找配置文件,该配置文件的命名规则是“servletName-servlet.xml”,例如 springmvc-servlet.xml。

也可以将 Spring MVC 的配置文件存放在应用程序目录中的任何地方,但需要使用 servlet 的 init-param 元素加载配置文件,通过 contextConfigLocation 参数来指定 Spring MVC 配置文件的位置,示例代码如下。

springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc-servlet.xml 1 springmvc /

此处使用 Spring 资源路径的方式进行指定,即 ​​classpath:springmvc-servlet.xml​​。

上述代码配置了一个名为“springmvc”的 Servlet。该 Servlet 是 DispatcherServlet 类型,它就是 Spring MVC 的入口,并通过 ​​1​​ 配置标记容器在启动时就加载此 DispatcherServlet,即自动启动。然后通过 servlet-mapping 映射到“/”,即 DispatcherServlet 需要截获并处理该项目的所有 URL 请求。

2)创建Spring MVC配置文件

在 WEB-INF 目录下创建 springmvc-servlet.xml 文件,如下所示。

3. 创建Controller

在 src 目录下创建 net.biancheng.controller 包,并在该包中创建 RegisterController 和 LoginController 两个传统风格的控制器类(实现 Controller 接口),分别处理首页中“注册”和“登录”超链接的请求。

Controller 是控制器接口,接口中只有一个方法 handleRequest,用于处理请求和返回 ModelAndView。

RegisterController 的具体代码如下。

package controller;import javax.servlet.javax.servlet.org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;public class LoginController implements Controller { public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { return new ModelAndView("/WEB-INF/jsp/register.jsp"); }}

LoginController 的具体代码如下。

package controller;import javax.servlet.javax.servlet.org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;public class RegisterController implements Controller { public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { return new ModelAndView("/WEB-INF/jsp/login.jsp"); }}

4. 创建View

index.jsp 代码如下。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here 未注册的用户,请 注册
已注册的用户,去 登录

在 WEB-INF 下创建 jsp 文件夹,将 login.jsp 和 register.jsp 放到 jsp 文件夹下。login.jsp 代码如下。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here 登录页面!

register.jsp 代码如下。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> Insert title here 注册页面!

将 springmvcDemo 项目部署到 Tomcat 服务器,首先访问 index.jsp 页面,如下图所示。

Controller及RequestMapping注解

Controller注解

package net.biancheng.controller;import org.springframework.stereotype.Controller;@Controllerpublic class IndexController { // 处理请求的方法}

例如,在 springmvcDemo 应用的配置文件 springmvc-servlet.xml 中添加以下代码:

RequestMapping注解

一个控制器内有多个处理请求的方法,如 UserController 里通常有增加用户、修改用户信息、删除指定用户、根据条件获取用户列表等。每个方法负责不同的请求操作,而 @RequestMapping 就负责将请求映射到对应的控制器方法上。

在基于注解的控制器类中可以为每个请求编写对应的处理方法。使用 @RequestMapping 注解将请求与处理方法一 一对应即可。

@RequestMapping 注解可用于类或方法上。用于类上,表示类中的所有响应请求的方法都以该地址作为父路径。

@RequestMapping 注解常用属性如下。

1. value 属性

value 属性是 @RequestMapping 注解的默认属性,因此如果只有 value 属性时,可以省略该属性名,如果有其它属性,则必须写上 value 属性名称。如下。

@RequestMapping(value="toUser")@RequestMapping("toUser")

value 属性支持通配符匹配,如 @RequestMapping(value="toUser/*") 表示 或 都能够正常访问。

2. path属性

path 属性和 value 属性都用来作为映射使用。即 @RequestMapping(value="toUser") 和 @RequestMapping(path="toUser") 都能访问 toUser() 方法。

path 属性支持通配符匹配,如 @RequestMapping(path="toUser/*") 表示 或 都能够正常访问。

3. name属性

name属性相当于方法的注释,使方法更易理解。如 @RequestMapping(value = "toUser",name = "获取用户信息")。

4. method属性

method 属性用于表示该方法支持哪些 HTTP 请求。如果省略 method 属性,则说明该方法支持全部的 HTTP 请求。

@RequestMapping(value = "toUser",method = RequestMethod.GET) 表示该方法只支持 GET 请求。也可指定多个 HTTP 请求,如 @RequestMapping(value = "toUser",method = {RequestMethod.GET,RequestMethod.POST}),说明该方法同时支持 GET 和 POST 请求。

5. params属性

params 属性用于指定请求中规定的参数,代码如下。

@RequestMapping(value = "toUser",params = "type")public String toUser() { return "showUser";}

以上代码表示请求中必须包含 type 参数时才能执行该请求。即 能够正常访问 toUser() 方法,而 则不能正常访问 toUser() 方法。

@RequestMapping(value = "toUser",params = "type=1")public String toUser() { return "showUser";}

以上代码表示请求中必须包含 type 参数,且 type 参数为 1 时才能够执行该请求。即 能够正常访问 toUser() 方法,而 则不能正常访问 toUser() 方法。

6. header属性

header 属性表示请求中必须包含某些指定的 header 值。

@RequestMapping(value = "toUser",headers = "Referer=表示请求的 header 中必须包含了指定的“Referer”请求头,以及值为“consumers属性

consumers 属性用于指定处理请求的提交内容类型(Content-Type),例如:application/json、text/html。如

@RequestMapping(value = "toUser",consumes = "application/json")。

8. produces属性

produces 属性用于指定返回的内容类型,返回的内容类型必须是 request 请求头(Accept)中所包含的类型。如 @RequestMapping(value = "toUser",produces = "application/json")。

除此之外,produces 属性还可以指定返回值的编码。如 @RequestMapping(value = "toUser",produces = "application/json,charset=utf-8"),表示返回 utf-8 编码。

使用 @RequestMapping 来完成映射,具体包括 4 个方面的信息项:请求 URL、请求参数、请求方法和请求头。

重定向和转发

Spring MVC 请求方式分为转发、重定向 2 种,分别使用 forward 和 redirect 关键字在 controller 层进行处理。

在 Spring MVC 框架中,控制器类中处理方法的 return 语句默认就是转发实现,只不过实现的是转发到视图。示例代码如下:

@RequestMapping("/register")public String register() { return "register"; //转发到register.jsp}

在 Spring MVC 框架中,重定向与转发的示例代码如下:

package net.biancheng.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/index")public class IndexController { @RequestMapping("/login") public String login() { //转发到一个请求方法(同一个控制器类可以省略/index/) return "forward:/index/isLogin"; } @RequestMapping("/isLogin") public String isLogin() { //重定向到一个请求方法 return "redirect:/index/isRegister"; } @RequestMapping("/isRegister") public String isRegister() { //转发到一个视图 return "register"; }}

拦截器

在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,主要有以下 2 种方式。

通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类(例如 HandlerInterceptorAdapter)来定义;通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。

配置:

在上述示例代码中,元素说明如下。

:该元素用于配置一组拦截器。:该元素是 的子元素,用于定义全局拦截器,即拦截所有的请求。:该元素用于定义指定路径的拦截器。:该元素是 的子元素,用于配置拦截器作用的路径,该路径在其属性 path 中定义。path 的属性值为​​/**​​​时,表示拦截所有路径,值为​​/gotoTest​​​时,表示拦截所有以​​/gotoTest​​结尾的路径。如果在请求路径中包含不需要拦截的内容,可以通过 子元素进行配置。

文件上传

Spring MVC 框架的文件上传基于 ​commons-fileupload​ 组件,并在该组件上做了进一步的封装,简化了文件上传的代码实现,取消了不同上传组件上的编程差异

在 Spring MVC 中实现文件上传十分容易,它为文件上传提供了直接支持,即 MultpartiResolver 接口。MultipartResolver 用于处理上传请求,将上传请求包装成可以直接获取文件的数据,从而方便操作。

MultpartiResolver 接口有以下两个实现类:

StandardServletMultipartResolver:使用了 Servlet 3.0 标准的上传方式。CommonsMultipartResolver:使用了 Apache 的 commons-fileupload 来完成具体的上传操作。

Maven 项目在 pom.xml 文件中添加以下依赖。

纯文本复制 commons-io commons-io 2.4 commons-fileupload commons-fileupload 1.2.2

文件下载

Spring MVC 文件下载的实现方法和实现过程;文件下载有以下两种实现方法:

通过超链接实现下载:实现简单,但暴露了下载文件的真实位置,并且只能下载 Web 应用程序所在目录下的文件,WEB-INF 目录除外。利用程序编码实现下载:增强安全访问控制,可以下载除 Web 应用程序所在目录以外的文件,也可以将文件保存到数据库中。

利用程序编码实现下载需要设置以下两个报头:

Web 服务器需要告诉浏览器其所输出内容的类型不是普通文本文件或 HTML 文件,而是一个要保存到本地的下载文件,这需要设置 Content-Type 的值为 application/x-msdownload。Web 服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置 Content-Disposition 报头。

该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在 attachment 后面还可以指定 filename 参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。

设置报头的示例如下:

response.setHeader("Content-Type", "application/x-msdownload");

response.setHeader("Content-Disposition", "attachment;filename="+filename);

/** * 执行下载 */ @RequestMapping("down") public String down(@RequestParam String filename, HttpServletRequest request, HttpServletResponse response) { String aFilePath = null; // 要下载的文件路径 FileInputStream in = null; // 输入流 ServletOutputStream out = null; // 输出流 try { // 从workspace\.metadata\.plugins\org.eclipse.wst.server.core\ // tmp0\wtpwebapps下载 aFilePath = request.getServletContext().getRealPath("uploadfiles"); // 设置下载文件使用的报头 response.setHeader("Content-Type", "application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=" + toUTF8String(filename)); // 读入文件 in = new FileInputStream(aFilePath + "\\" + filename); // 得到响应对象的输出流,用于向客户端输出二进制数据 out = response.getOutputStream(); out.flush(); int aRead = 0; byte b[] = new byte[1024]; while ((aRead = in.read(b)) != -1 & in != null) { out.write(b, 0, aRead); } out.flush(); in.close(); out.close(); } catch (Throwable e) { e.printStackTrace(); } logger.info("下载成功"); return null; }


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:一篇文章教会你使用java爬取想要的资源
下一篇:Java程序单实例运行的简单实现
相关文章

 发表评论

暂时没有评论,来抢沙发吧~