Spring MVC(二)

1. 注解@RequestMapping修饰类

在Spring MVC中一般都是使用注解@RequestMapping来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置的映射地址作用一致。在上一节的内容中,我们通过注解@RequestMapping改进了程序,让请求地址可以在方法中通过注解@RequestMapping来指定,代码显得非常简洁。

注解@RequestMapping不仅可以修饰方法,还可以用来修饰类。在实际的项目中,大多都是采用模块化的编程,每个模块肯定各需要一个控制器,控制器中的不同方法对应不同的请求地址。在使用注解@RequestMapping修饰方法时,需要分别制定相应的请求地址,具体的代码如下所示。

java 复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * 商品模块控制器
 */
@Controller
public class ProductController {
	@RequestMapping("/product/add")
	public String add() {
		System.out.println("商品添加测试");
		return "product/add";
	}
	@RequestMapping("/product/update")
	public String update() {
		System.out.println("商品修改测试");
		return "product/update";
	}
	@RequestMapping("/product/list")
	public String list() {
		System.out.println("商品列表测试");
		return "product/list";
	}
}

在每次编写操作方法的时候,都需要在相应的方法中加入相同的表示模块的映射地址("/product")。这样的话操作起来就会显得稍微麻烦一点,如果能在定义一个控制器的时候,就能指定代表模块的映射地址不是更好吗?

注解@RequestMapping除了可以修饰方法,也可以用来修饰类。在类中加入注解@RequestMapping,就可以给这个控制器添加一个映射地址,其他的方法中就可以直接指定具体的访问地址即可,代码如下。

java 复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * 商品模块控制器
 */
@Controller
@RequestMapping("/product")
public class ProductController {
	@RequestMapping("/add")
	public String add() {
		System.out.println("商品添加测试");
		return "product/add";
	}
	@RequestMapping("/update")
	public String update() {
		System.out.println("商品修改测试");
		return "product/update";
	}
	@RequestMapping("/list")
	public String list() {
		System.out.println("商品列表测试");
		return "product/list";
	}
}

此时,访问商品模块中的各方法,就可以通过类中的注解和方法中的注解共同组合成一个完整的映射地址,编写的时候就轻松了许多。

2. 注解@RequestMapping修饰方法

在学习Servlet的时候,曾经对HTTP协议有过一些了解,一个完整的请求由三部分组成,分别是:请求行、消息报头、请求正文,其中请求行又包括:请求方法、请求地址、协议版本,通过这些信息就可以确定一个完整请求地址,最终访问到相应的资源。其中请求方法最常用的就是GET和POST,请求地址就是URL地址,请求报头是客户端向服务器端传递请求的附加信息以及客户端自身的信息,请求正文中包括发送请求所传递的参数等信息。

通过注解@RequestMapping可以对HTTP协议的内容进行详细映射,前面我们已经用到了请求地址的映射,其实注解@RequestMapping除了可以映射请求地址外,还可以对请求方法、请求头、请求参数等信息映射请求。@RequestMapping有四个参数,分别是:value、method、heads、params,分别表示请求URL、请求方法、请求头和请求参数。这四个参数之间是与的关系,联合使用多个条件映射,可以增加请求映射的精确性。注解@RequestMapping默认为请求URL,之前的例子中注解@RequestMapping中添加的就是映射地址,四个参数中最为常用的就是请求地址和请求方法。

使用注解@RequestMapping来设置请求方法具体使用代码如下。

java 复制代码
@RequestMapping(value="/add", method=RequestMethod.POST)
public String add() {
	System.out.println("商品添加测试");
	return "redirect:/product/list";//目标重定向
}

注意:处理完成以后,返回值是以"redirect:"开头的,这表示目标重定向,也就是我们俗称的客户端跳转

此时访问这个方法的时候,请求类型就必须是POST,否则就会出现错误。因此在具体的操作时候,我们可以通过请求类型来指定具体的操作方法,HTTP请求的类型有GET、POST、PUT、DELETE等。通过注解@RequestMapping可以指定所要处理的请求类型,代码如下所示。

java 复制代码
/**
 * 处理修改操作
 */
@RequestMapping(value="/update", method=RequestMethod.PUT)
public String update() {
	System.out.println("商品修改测试");
	return "redirect:/product/list";
}

/**
 * 处理删除操作
 */
@RequestMapping(value="/delete", method=RequestMethod.DELETE)
public String delete() {
	System.out.println("商品删除测试");
	return "redirect:/product/list";
}

**注意:**以上的写法不是最终开发的代码,在接下来的章节中会做更正,在此只是简单的演示操作。

在学习Servlet的时候,通过表单只能是以GET或POST提交方式,要实现PUT和DELETE提交,需要借助于HiddenHttpMethodFilter过滤器操作,以下是HiddenHttpMethodFilter类的部分源代码。

java 复制代码
/** Default method parameter: {@code _method} */
public static final String DEFAULT_METHOD_PARAM = "_method";

private String methodParam = DEFAULT_METHOD_PARAM;


/**
* Set the parameter name to look for HTTP methods.
* @see #DEFAULT_METHOD_PARAM
*/
public void setMethodParam(String methodParam) {
	Assert.hasText(methodParam, "'methodParam' must not be empty");
	this.methodParam = methodParam;
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
		throws ServletException, IOException {

	HttpServletRequest requestToUse = request;

	if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
		String paramValue = request.getParameter(this.methodParam);
		if (StringUtils.hasLength(paramValue)) {
			requestToUse = new HttpMethodRequestWrapper(request, paramValue);
		}
	}

	filterChain.doFilter(requestToUse, response);
}

通过源码可以发现,实现PUT和DELETE提交,需要通过POST提交转换,在提交的时候必须传入一个参数,参数名是"_method"。如果需要转换为PUT提交,传入的参数值是"PUT",如果需要转换为DELETE提交,传入的参数值是"DELETE"。在具体的操作时,首先要配置这个过滤器,在web.xml文件中添加配置,代码如下。

XML 复制代码
<filter>
  <filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>HiddenHttpMethodFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

在具体的JSP页面操作的代码如下。

html 复制代码
<!-- POST提交转PUT提交 -->
<form action="product/update" method="post">
	<input type="hidden" name="_method" value="PUT">
	<input type="submit" value="PUT提交">
</form>

<!-- POST提交转DELETE提交 -->
<form action="product/update" method="post">
	<input type="hidden" name="_method" value="DELETE">
	<input type="submit" value="DELETE提交">
</form>

在每个表单中,都有一个隐藏表单域,用来指定提交的类型,这样做不仅可以实现参数传递,同时也不影响页面中的标签显示。

注解@RequestMapping可以指定一个详细的URL地址,在被注解的方法中,就不需要考虑请求路径问题了,可以着重编写具体的业务代码,真正做到了请求和响应互不交叉。

相关推荐
2402_857589367 分钟前
SpringBoot框架:作业管理技术新解
java·spring boot·后端
HBryce2411 分钟前
缓存-基础概念
java·缓存
一只爱打拳的程序猿26 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
杨荧27 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck29 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
为将者,自当识天晓地。1 小时前
c++多线程
java·开发语言
daqinzl1 小时前
java获取机器ip、mac
java·mac·ip
激流丶1 小时前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
Themberfue1 小时前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·