Java EE SSM框架整合开发(九)Spring MVC的Controller

831 阅读4分钟

注解Controller和RequestMapping

在前面的样例中,在springmvc-servlet.xml中配置的超链接请求与控制器之间的映射关系,在这里我们使用注解配置映射关系(记得开启扫描)。

使用基于注解的控制器,具有如下两个优点:

  • 可以在一个控制器类中编写多个处理方法,进而可以处理多个请求,减少控制器类的数量,方便后期的维护。不像在配置文件中部署映射每个控制器类只能对应一个请求。
  • 不需要在配置文件中部署映射,仅需要使用RequestMapping注释类型注解一个方法进行请求处理。

RequestMapping注解分两种方法级别注解和类级别注解

1.1 方法级别

@RequestMapping(value = "/index/login")

value属性将请求URI映射到方法,是RequestMapping注解的默认属性,如果只有一个value属性,可以省略“value=”。

在上次项目的基础上

  1. 在springmvc-servlet开启注解扫描
<?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 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<context:component-scan base-package="com.controller" />
	
	<!-- 为控制器返回值自动添加前缀后缀 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver"
		id="internalResourceViewResolver">
		<!-- 前缀 -->
		<property name="prefix" value="/WEB-INF/jsp/" />
		<!-- 后缀 -->
		<property name="suffix" value=".jsp" />
	</bean>
</beans>
  1. 修改控制器类
@Controller
public class IndexController {
    @RequestMapping(value = "/index/login")
    public String login() {
        /**return 的 login代表逻辑视图名称,需要根据Spring MVC配置
         * 文件中internalResourceViewResolver的前缀和后缀找到对应的物理视图
         */
        return "login";
    }
    @RequestMapping(value = "/index/register")
    public String register() {
        return "register";
    }
}

1.2 类级别

@Controller
@RequestMapping("/index")
public class IndexController {
    @RequestMapping("/login")
    public String login() {
        return "login";
    }
    @RequestMapping("/register")
    public String register() {
        return "register";
    }
}

Controller接收请求参数的常见方式

2.1 通过实体bean接收请求参数

  1. 建立参数们对应的JavaBean
package pojo;
public class UserForm {
    private String uname;//与请求参数名称相同
    private String upass;
    private String reupass; 
    //getter和setter
}
  1. 修改JSP页面 login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
	</head>
	<body>
		登录页面。
		
		<form action="${pageContext.request.contextPath }/main" method="post">
			<table>
				<tr>
					<td>姓名:</td>
					<td><input type="text" name="uname" class="textSize"></td>
				</tr>
				<tr>
					<td>密码:</td>
					<td><input type="password" name="upass" class="textSize"></td>
				</tr>
				
				<tr>
					<td colspan="2"><button onclick="gogo()"/> <button onclick="cancel()"/></td>
				</tr>
				
			</table>
			${messageError}
		</form>
		
	</body>
</html>

main.jsp,作为登陆成功页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>主页面</title>
    </head>
    <body>
        欢迎${sessionScope.u.uname }访问该系统。
    </body>
</html>
  1. 修改控制器类
@RequestMapping("/main")
public String main(UserForm user, HttpSession session, Model model) {
        if("herlo".equals(user.getUname())&&"123456".equals(user.getUpass())) {
                session.setAttribute("u", user);
                return "main";
        }
        else {
                model.addAttribute("messageError", "用户名或密码错误");
                return "login";
        }
}

2.2 通过处理方法的形参接收请求参数

通过处理方法的形参接收请求参数,也就是直接把表单参数写在控制器类方法的形参中,即形参名称与请求参数名称完全相同。该接收参数方式适用于get和post提交请求方式。

/** 
* 处理注册 使用UserForm对象(实体JavaBean)接收注册页面提交的请求参数
*/
@RequestMapping("/register")
public String register(String uname,String upass, Model model) {
    if ( "zhangsan".equals(uname)&&"123456".equals(upass) ) {
    //awa
    } 
}

2.3 通过HttpServletRequest接收请求参数

通过HttpServletRequest接收请求参数,适用于get和post提交请求方式。

<a href="${pageContext.request.contextPath}/register?param=test">注册</a>
@Controller
public class RegisterController{
	@RequestMapping("/register")
	public String register(HttpServletRequest request, Model model) {
		System.out.println(request.getParameter("param"));
		return "register";
	}
}

2.4 通过@PathVariable接收URL中的请求参数

  • @PathVariable无法接收对象,但是可以接收多个值。
  • @PathVariable("xxx")通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中
<h1>pathVariable</h1>
<a href="${pageContext.request.contextPath}/hello/pathVariable/bigsea" > name is bigsea </a>
<br/>
<a href="${pageContext.request.contextPath}/hello/pathVariable/sea" > name is sea</a>
<br/>
/**
 * localhost:8080/springmvc/hello/pathVariable/bigsea
 * localhost:8080/springmvc/hello/pathVariable/sea
 * 这些URL 都会 执行此方法 并且将  <b>bigsea</b>、<b>sea</b> 作为参数 传递到name字段
 */
@RequestMapping("/pathVariable/{name}")
public String pathVariable(@PathVariable("name")String name){
        System.out.println("hello "+name);
        return "helloworld";
}

2.5 通过@RequestParam接收请求参数

  • 通过@RequestParam接收请求参数,适用于get和post提交请求方式。
  • 通过@RequestParam接收请求参数与2.2“通过处理方法的形参接收请求参数”的区别是:当请求参数与接收参数名不一致时,后者不会报404错误,而“通过@RequestParam接收请求参数”会404错误。
/** * 处理注册 使用@RequestParam接收请求参数*/
@RequestMapping("/register")
public String register(@RequestParam String uname, @RequestParam String upass, Model model) {
    if ("zhangsan".equals(uname)&&"123456".equals(upass)) {
    //awa
    }
}

2.6 通过@ModelAttribute接收请求参数

  • @ModelAttribute注解放在处理方法的形参上时,用于将多个请求参数封装到一个实体对象,自动暴露为模型数据用于视图页面展示时使用。而2.1中只是将多个请求参数封装到一个实体对象,并不能暴露为模型数据(需要使用model.addAttribute语句才能暴露为模型数据,数据绑定与模型数据展示,可参考第12章的内容)。
  • 通过@ModelAttribute注解接收请求参数,适用于get和post提交请求方式。

就是用@ModelAttribute xxx替代了原来的model.addAttribute(xxx,xxx)

@RequestMapping("/register")
public String register(@ModelAttribute("user") UserForm user) {
    if ("zhangsan".equals(uname) && "123456".equals(upass)) {
        logger.info("成功");
        return "login"; // 注册成功,跳转到 login.jsp
    } else {
        logger.info("失败");
        // 使用@ModelAttribute("user")与model.addAttribute("user",user)的功能相同
        //register.jsp页面上可以使用EL表达式${user.uname}取出ModelAttribute的uname值
        return "register"; // 返回 register.jsp
    }
}

重定向与转发

重定向是将用户从当前处理请求定向到另一个视图(例如JSP)或处理请求,以前的请求(request)中存放的信息全部失效,并进入一个新的request作用域;

转发是将用户对当前处理的请求转发给另一个视图或处理请求,以前的request中存放的信息不会失效。 转发是服务器行为,重定向是客户端行为。