`

SpringMVC之用注解控制器

 
阅读更多

在传统的Spring MVC开发方法中,必须在Bean配置文件中为每个控制器类配置实例和请求映射和让每个控制器类去实现或者扩展特定于框架的接口或者基类,不够灵活。

如果Spring MVC可以自动侦测你的控制器类和请求映射,就能减少配置所需要的工作量。

Spring2.5支持一种基于注解的控制器开发方法。

Spring可以通过@Controller注解自动发现你的控制器类以及@RequestMapping注解中的请求映射,这样就为你免去了在Bean配置文件中配置它们的麻烦。此外,如果使用注解,控制器类和处理程序方法在访问上下文资源(例如请求参数、模型属性和会话属性)时也会更加灵活。

常用到的注解

 

1@Controller
 
2@RequestMapping
 
3@RequestParam,  @PathVariable,  @CookieValue
 
@Controller注解能将任意的类标注成控制器类。与传统的控制器相反,被标注的控制器类不需要实现特定于框架的接口,也不必扩展特定于框架的基类
在控制器类内部,可能有一个或者多个处理程序方法添加了@RequestMapping注解。
 

 

处理程序方法的签名非常灵活。你可以为处理程序方法指定任意的名称,并定义以下任意一种类型作为它的方法参数。在这里,只提到了常见的参数类型。关于有效参数类型的完整列表,请参阅有关配置基于注解的控制器的Spring文档。

 

见的参数类

 

1.HttpServletRequest、HttpServletResponse或HttpSession。

2.添加了@RequestParam注解的任意类型的请求参数

3.添加了@ModelAttribute注解的任意类型的模型属性

4.任意类型的命令对象,供Spring绑定请求参数

5.Map或者ModelMap,供处理程序方法向模型添加属性

6.Errors或者BindingResult,让处理程序方法访问命令对象的绑定和验证结果

7.SessionStatus,让处理程序方法发出会话处理已经完成的通知

 

 

常见的返回值类型

 

处理程序方法的返回类型可以是ModelAndView、Model、Map、String、void

 

 

在创建基于注解的控制器之前,必须构建web应用程序上下文来处理注解。

首先,为了让Spring用@Controller注解自动侦测控制器,必须通过<context:component-scan>元素启用Spring的组件扫描特性。

其次Spring MVC还能够根据@RequestMapping将请求映射到控制器类和处理程序方法。

为了使其生效,必须在web应用程序上下文中注册DefaultAnnotationHandlerMapping实例和AnnotationMethodHandlerAdapter实例。

它们分别处理在类级别方法级别上的@RequestMapping注解

 

 

必要的Spring MVC配置

<?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:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/mvc/spring-mvc
          http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 自动扫描注解的Controller -->
	<context:component-scan base-package="com.wy.controller.annotation" />
	
	<!-- 处理在类级别上的@RequestMapping注解-->
	<bean
		class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
	<!-- 处理方法级别上的@RequestMapping注解-->
	<bean
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
	 
	 
	<!-- 视图解析器策略 和 视图解析器 -->
	<!-- 对JSTL提供良好的支持 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 默认的viewClass,可以不用配置
		<property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView" />
		 -->
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp" />
	</bean>
		
</beans>

 DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter是默认在Web应用程序上下文中预先注册好的。然而,如果你还显式地注册了其他的处理程序映射或者处理程序适配器,它们就不会自动注册了。在这种情况下,你必须亲自注册它们。

 

基于注解的控制器类可以是个任意类,不实现特殊接口,也不扩展特殊的基类。你只要用@Controller注解对它进行标注即可。还可以在控制器中定义一个或者多个处理程序方法来处理单个或者多个动作。处理程序方法的签名很灵活,足以接受一系列参数。

 

 

@RequestMapping注解可以被应用到类级别或者方法级别上

 

 

 

 

 

 

 

 

 

 

 

Controller层:代码中写了很详细的注释

package com.wy.controller.annotation;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.WebRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;

import com.wy.pojo.User;

/**
 * @author Administrator
 * @version 2011-12-3
 */

@Controller
@RequestMapping("userManagerContoller") //指定请求路径,相对路径可以不定义
public class UserManagerContoller {

	/**
	 * 欢迎
	 * @return
	 */
	
	/* 1.传统的获取请求的参数方式
	 * http://localhost:8080/SpringMVC/userManagerContoller/welcome.do?name=wy
	 */
	@RequestMapping("/welcome") 
	public ModelAndView welcome(HttpServletRequest request){  
		ModelAndView mav = new ModelAndView();
		String name = request.getParameter("name");
        Date today = new Date();  
        String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(today);
        mav.addObject("today", date);
        mav.addObject("name", name);
        mav.setViewName("welcome");
        return mav;  
    }
	
	/* 2.restful风格获取请求的参数方式  Spring3.0的一个重要变化(将参数放到了请求路径中)
	 * http://localhost:8080/SpringMVC/userManagerContoller/welcome/wy.do
	 * 
	 * 注意点: JVM将Java文件编译成Class文件有两种模式 Debug 和Release
	 * 这两种编译方式的区别是:
	 *    Debug 包含额外的调试信息,可以完整的保留变量的名称 (Eclipse 使用的是Debug)
	 *    Release 把变量名称使用其他的一些符号代替,量名称就不可见啦 (在使用 javac命令)   
	 */
	@RequestMapping("/welcome/{param}/{sex}")
	//前一个“param是防止Release编译下找不到参数名称,因此要指定;要和模板中定义的参数名称一致
	//后面一个“param”可以和模板中定义的参数名称不一致,建议还是一致
	public ModelAndView welcome(@PathVariable("param") String param, @PathVariable("sex") String xingbie){
		ModelAndView mav = new ModelAndView();
		mav.addObject("name", param);
		mav.addObject("sex", xingbie);
		Date today = new Date();  
        String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(today);
        mav.addObject("today", date);
        mav.setViewName("welcome");
		return mav;
	}
	
	/**
	 * 3.不同请求方式(get,post),映射不同的方法
	 * 
	 *   value 指定请求路径,method 指定请求方式
	 */
	@RequestMapping(value="/welcome", method=RequestMethod.GET)
	public ModelAndView requestMethodGet(){
		ModelAndView mav = new ModelAndView();
		mav.setViewName("welcome");
		return mav;
	}

	@RequestMapping(value="/hello", method=RequestMethod.POST)
	public ModelAndView requestMethodPost(){
		ModelAndView mav = new ModelAndView();
		mav.setViewName("hello");
		return mav;
	}
	
	/**
	 * 4. @RequestParam 使用方法和@PathVariable类似(要注意Debug和Release)
	 *    http://localhost:8080/SpringMVC/userManagerContoller/welcomeParam.do?username=wy&password=123&age=23
	 */
	@RequestMapping(value="/welcomeParam", method=RequestMethod.GET)
	public ModelAndView welcome(@RequestParam("username") String username,
			@RequestParam("password") String password, @RequestParam("age") int age) {
		ModelAndView mav = new ModelAndView();
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);
		user.setAge(age);
		mav.addObject("user", user);
		mav.setViewName("hello");
		return mav;
	}
	
	/**
	 * 5.获取表单中的值
	 *   BindingResult 绑定数据过程中产生的错误注入到BindingResult中。
	 */
	@RequestMapping(value="/welcome", method=RequestMethod.POST)
	public ModelAndView commonCommod(User user, BindingResult result){
		ModelAndView mav = new ModelAndView();
		mav.addObject(user);
		if(result.hasErrors() && result.hasFieldErrors()){
			String field = null;
			Object fieldValue = null;
			Map<String, Object> map = new HashMap<String, Object>();
			List<FieldError> fieldErrors = result.getFieldErrors();
			for(FieldError fieldError : fieldErrors){
				field = fieldError.getField();
				fieldValue = fieldError.getRejectedValue();
				
				map.put(field, fieldValue);
			}
			mav.addObject("map", map);
			mav.setViewName("welcome");
		}else{
			mav.setViewName("hello");
		}
		return mav;
	}
	
	/**
	 * 属性编辑器 类型转换
	 * 典型应用: 日期转换
	 */
	@InitBinder
	public void initBinder(WebRequestDataBinder binder){
		binder.registerCustomEditor(Date.class, new CustomDateEditor(
				new SimpleDateFormat("yyyy-MM-dd"),false));
	}
	
	public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception{
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
	}
	/**
	 * 6.常用的参数
	 *   使用Session有一个前提就是session必须是可用的
	 */
//	public ModelAndView commonArguments(HttpServletRequest request, HttpServletResponse response, HttpSession session, 
//			@CookieValue AnyType cookieName, @RequestHeader("user-Agent") AnyType name, 
//	        @PathVariable AnyType variableName, @RequestParam AnyType paramName){
//		ModelAndView mav = new ModelAndView();
//		
//		return mav;
//	}
	
	/**
	 * 7.返回类型
	 *   void 、String、AnyType(任意对象)、Model、ModelAndView
	 *   说明:Model继承了Map,为SpringMVC定制的
	 */
	// void
	@RequestMapping
	public void commonReturnType(HttpServletResponse response){
		try {
			PrintWriter out = response.getWriter();
			out.println("向页面中输出的值");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@RequestMapping
	public void commonReturnType(PrintWriter out){//其实也是从HttpServletResponse 通过getWriter()得到out
		out.println("向页面中输出的值");
	}
	
	@RequestMapping("/commonReturnType")
	public void commonReturnType(){
		//默认生成隐含的viewName(规则测略:按照请求路径${appName/userManagerContoller/commonReturnType.do 
		//                                   ---> userManagerContoller/commonReturnType}
        //		                             ---> /WEB-INF/page/userManagerContoller/commonReturnType.jsp
	    //                  )
	}
	
	// String
	/**
	 * ModelAndView中的Model
	 * ModelAndView中的View
	 */
	@RequestMapping
	public String commonReturnType(Map<Object, Object> model){//model
		model.put("", "");
		return "viewName";
	}
	
	//AnyType(任意对象)
	/**
	 * user放到model中,model(key, value) key默认是取Bean的名称将其首字母小写 即user,value即user
	 * 默认生成隐含的viewName
	 * 在页面上可以使用request.getAttribute("user")或者${user.key} ${user.value}
	 * @return
	 */
	@RequestMapping
	public User commonReturnTypeUser(){//
		User user = null;
		
		return user;
	}
	
	/**
	 * userList放到model中,model(key, value) key默认是框架生成userList,value即user
	 * 默认生成隐含的viewName
	 * 在页面上可以使用request.getAttribute("userList")或者${userList.key} ${userList.value}
	 * @return
	 */
	@RequestMapping
	public List<User> commonReturnTypeUserList(){
        List<User> userList = null;
		
		return userList;
	}
	
	/**
	 * 
	 * 默认生成隐含的viewName
	 * @return
	 */
	@RequestMapping
	public Model commonReturnTypeModel(){
		Model model = null;
		
		return model;
	}
	
	/**
	 * 
	 * @return
	 */
	@RequestMapping
	public ModelAndView commonReturnTypeModelAndView(){
		ModelAndView mav = new ModelAndView();
		
		mav.addObject("", "");
		mav.setViewName("");
		return mav;
	}
	
}

 

view层

  welcome.jsp

  

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
%>
<!DOCTYPE html>
<html>
  <head>
    <title>welcome.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my annotation HTML page. <br/>
          今天是: ${today}<br/>
          参数是: ${name}&nbsp;&nbsp;&nbsp;${sex}<br/>
    <hr/>     
    <c:forEach var="field" items="${map}">
       <c:if test="${field != null}" var="param" scope="page">
                          您输入的${field.key}不正确! ${field.value}<br/>
    </c:if>
    </c:forEach>
    
    <form action="<%=path%>/userManagerContoller/welcome.do" method="post">
                   用户名: <input type="text" id="username" name="username"  value="wy" /><br/>
                   密码 : <input type="text" id="password" name="password"  value="wy" /><br/>
                   年龄 : <input type="text" id="age"      name="age"       value="23wy" /><br/>          
       <input type="submit" value="提交" />
    </form>          
  </body>
</html>

 

 

值得注意的点:

    1、@PathVariable("paramName") @RequestParam("paramName") 建议指定参数名称

         原因是VM将Java文件编译成Class文件有两种模式 Debug 和Release

         这两种编译方式的区别是:

               Debug 包含额外的调试信息,可以完整的保留变量的名称 (Eclipse 使用的是Debug)

                Release 把变量名称使用其他的一些符号代替,量名称就不可见啦 (在使用 javac命令)

       2、restful风格获取请求的参数方式

       3、参数类型转换

             注册属性编辑器

      4、对于无任何输出的方法

       

@RequestMapping("/commonReturnType")
	public void commonReturnType(){
		//默认生成隐含的viewName(规则测略:按照请求路径${appName/userManagerContoller/commonReturnType.do 
		//                                   ---> userManagerContoller/commonReturnType}
        //		                             ---> /WEB-INF/page/userManagerContoller/commonReturnType.jsp
	    //                  )
	}

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    SpringMVC注解驱动的控制器详解

    SpringMVC注解驱动的控制器详解,具体效果与过程看博文 http://blog.csdn.net/evankaka/article/details/45562951

    springmvc非注解controller控制器

    springmvc非注解controller控制器

    手写SpringMVC注解动态调用控制器方法.zip

    刚接触SpringMVC几天、代码肯定比不上大佬ε...初步使用反射注解实现动态调用方法 初步了解SpringMVC @Controller、@RequestMapping、@requestParam用法及原理 _φ(❐_❐✧ 人丑就要多读书 不熬夜不追剧~( ̄▽ ̄)~* 

    springmvc注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证

    springmvc注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证 参数传递

    springmvc基础.docx

    springmvc基础 包含代码+知识点+详细解释 1. 什么是springmvc? 2. springmvc框架原理 ...5. springmvc注解开发 常用的注解学习 参数绑定(简单类型、pojo、集合类型) 自定义参数绑定 6. springmvc和struts2区别

    springmvc常用注解标签详解

    springmvc常用注解标签详解,@Controller控制器Controller 负责处理由DispatcherServlet 分发的请求,@RequestMappingRequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有...

    SpringMVC注解开发的详解.doc

    该文档是关于SpringMVC注解开发的详解,如:@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@...

    springmvc入门程序(下载后你不会后悔的)

    springmvc框架原理(掌握) 前端控制器、处理器映射器、...springmvc注解开发:(掌握) 常用的注解学习 参数绑定(简单类型、pojo、集合类型(明天讲)) 自定义参数绑定(掌握) springmvc和struts2区别

    SpringMVC教程

    非常棒的SpringMVC教程, 简明 透彻 涵盖了基本工作中都会接触到的知识 每一章都是一个PDF,效果非常清楚 即有Spring2.5的 Controller接口的老版本 ...第六章 注解式控制器详解5(SpringMVC强大的数据绑定2).pdf

    springmvc第一天课堂笔记

    springmvc框架原理(掌握) ...springmvc注解开发:(掌握) 常用的注解学习 参数绑定(简单类型、pojo、集合类型(明天讲)) 自定义参数绑定(掌握) springmvc和struts2区别 springmvc和struts2的区别

    跟我学SpringMVC

    在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 第三章 DispatcherServlet详解 第四章 Controller接口控制器详解(1) ...第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证

    跟我学SpringMVC 教程

    在线版目录 第一章 Web MVC简介 第二章 Spring MVC入门 第三章 DispatcherServlet详解 第四章 Controller接口控制器详解(1) ...第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证

    SpringMVC面试专题.pdf

    8、SpingMvc 中的控制器的注解一般用那个,有没有别的注解可以替代? 9、 @RequestMapping 注解用在类上面有什么作用? 10、怎么样把某个请求映射到特定的方法上面? 11、如果在拦截请求中,我想拦截 get 方式提交的...

    SpringMVC实现笔记_SpringMVC实现笔记_

    开发步骤①导入SpringMVC相关坐标②配置SpringMVC核心控制器DispathcerServlet③创建Controller类和视图页面④使用注解配置Controller类中业务方法的映射地址⑤配置SpringMVC核心文件 spring-mvc.xml⑥客户端发起...

    尚硅谷_SpringMVC.docx

    SpringMVC通过一套MVC注解,让POJO成为处理请求的控制器,而不需要实现任何接口,同时SpringMVC还支持REST风格的URL请求。SpringMVC在框架设计、扩展性、灵活性方面全面超越了Struts、WebWork MVC框架,从原来的追赶...

    SpringMVC 02 基于注解的控制器开发使用

    创建基于注解控制器的应用实现(注册和登录) 1.目录结构 3.3 Controller 文件 indexController package com.dhl.backstage.controller; import org.springframework.stereotype.Controller; import org....

    springMVC_day01.xmind

    SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于...它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求

    2021全新SpringMVC教程

    15_SpringMVC_控制器中有多个方法对应同一个请求的情况.mp4 17_SpringMVC_@RequestMapping注解的value属性.mp4 20_SpringMVC_测试form表单是否能够发送put和delete请求方式的请求.mp4 22_SpringMVC_@RequestMapping...

    Spring SpringMVC 简单整合

    1、 用户发送请求至前端控制器DispatcherServlet。 2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器...

    Spring MVC学习(六)-------注解式控制器详解1

    Spring MVC学习(六)-------注解式控制器详解1

Global site tag (gtag.js) - Google Analytics