Spring MVC注解说明示例

1 篇文章 0 订阅
1 篇文章 0 订阅

@Controller

注解一个类表示控制器,Spring MVC会自动扫描标注了这个注解的类。

@Controller
@RequestMapping("goods") 
public class GoodsController extends BaseController{
}


@Service

将自动注册到Spring容器,加在业务层,一般对于接口和实现。


@Qualifier 

如果一个接口有多个实现,那么注入时候加上唯一标示

同时有下述两个实现类 EmployeeServiceImpl和EmployeeServiceImpl1:

@Service("service")
public class EmployeeServiceImpl implements EmployeeService {
    public EmployeeDto getEmployeeById(Long id) {
        return new EmployeeDto();
    }
}

@Service("service1")
public class EmployeeServiceImpl1 implements EmployeeService {
    public EmployeeDto getEmployeeById(Long id) {
        return new EmployeeDto();
    }
}

调用的时候必须指定一个。

@Controller
@RequestMapping("/emplayee.do")
public class EmployeeInfoControl {
    
    @Autowired
    @Qualifier("service")
    EmployeeService employeeService;
    
    @RequestMapping(params = "method=showEmplayeeInfo")
    public void showEmplayeeInfo(HttpServletRequest request, HttpServletResponse response, EmployeeDto dto) {
        #略
    }
}


@Autowried

它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过 @Autowired的使用来消除 set ,get方法
默认是按照类型进行装配注入,默认情况下,它要求依赖对象必须存在,如果允许 null 值,可以设置它 required 为false。

如果我们想要按名称进行装配的话,可以添加一个 @Qualifier 注解解决。

	/**
	 * 商品规格业务数据库操作类
	 */
	@Autowired
	private GoodsSpecificBlo goodsSpecificBlo;
	
	/**
	 * 商品业务数据库操作类
	 */
	@Autowired
	private GoodsBlo goodsBlo;
	
	/**
	 * 商品快照数据库操作类
	 */
	@Autowired
	private GoodsSnapshotBlo goodsSnapshotBlo;


@RequestMapping

请求路径映射,可以标注类,也可以是方法,可以指定请求类型,默认不指定为全部接收。

指定方法

    @RequestMapping(value="/new", method = RequestMethod.GET)  
    public AppointmentForm getNewForm() {  
        return new AppointmentForm();  
    }  
@Controller
@RequestMapping("goods") 
public class GoodsController extends BaseController{
	
	/**
	 * GoodsService业务操作Service
	 */
	@Autowired
	private  GoodsService goodsService;
	
	/**
	 * 评价业务操作Service
	 */
	@Autowired
	private EvaluationService evaluationService;
	
	/**
	 * 
	 * 模块访问方法:商品一览界面<br/>
	 * @param  request http请求实例
	 * @return 返回页面名称
	 * @throws Exception
	 */
	@RequestMapping(value = "/list.htm") 
	public String GoodsList(HttpServletRequest request, GoodsVO goods) throws Exception {
		// doSearch实现初期进入一览画面,不做查询
		String doSearch = request.getParameter("doSearch");
		if (StringUtil.isNotBlank(doSearch)) {
			goodsService.search(request, goods);
		}
		// 跳转页面
		return "goods/goods_list";
	}
}


@RequestParam

放在参数前,表示只能接收参数a=b格式的数据,@RequestParam是传递参数的. 用于将请求参数区数据映射到功能处理方法的参数上。

指定传入的参数名

public void getUser( @RequestParam(value="user") String userName, @RequestParam(value="pass") String userPassword,
       HttpServletRequest request) 

通过required=false or true ,指定该参数是否必须要传,如果为true,则该参数必须传;如果为false, 则可以不传,会默认赋值为null 

如果用@RequestParam注解的参数是int基本类型,但是required=false,这时如果不传参数值会报错,因为不传值,会赋值为null给int.最好用包装类型。

public void getUser( @RequestParam(value="user",required = true) String userName,
       @RequestParam(value="pass",required = false) String userPassword,) 

如果不用@RequestParam注解,也可以获得参数,如果没有传该参数不会报错。

public void getUser( String userName, String userPassword) 


@RequestBody

放在参数前,表示参数从request body中获取,而不是从地址栏获取,所以这肯定是接收一个POST请求的非a=b格式的数据,@RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。

然而在ajax请求往往传的都是Json对象,后来发现用 JSON.stringify(data)的方式就能将对象变成字符串。同时ajax请求的时候也要指定dataType: "json",contentType:"application/json" 这样就可以轻易的将一个对象或者List传到Java端,使用@RequestBody即可绑定对象或者List.

<script type="text/javascript">  
    $(document).ready(function(){  
        var saveDataAry=[];  
        var data1={"userName":"test","address":"gz"};  
        var data2={"userName":"ququ","address":"gr"};  
        saveDataAry.push(data1);  
        saveDataAry.push(data2);         
        $.ajax({ 
            type:"POST", 
            url:"user/saveUser", 
            dataType:"json",      
            contentType:"application/json",               
            data:JSON.stringify(saveData), 
            success:function(data){ 
                                       
            } 
         }); 
    });  
</script> 
   @RequestMapping(value = "saveUser", method = {RequestMethod.POST }}) 
    @ResponseBody  
    public void saveUser(@RequestBody List<User> users) { 
         // TODO
    } 

再看一个例子

$.ajax({
      type: "post",
      contentType:"application/json",
      url: "repairs/saveDispatches",
      data: JSON.stringify(dispatchesDTO),
      success: function(data){
        	if(!data.success){
       
        	}else{
          alertSuccess("派工成功");
      }
    })
@RequestMapping("/repairs/saveDispatches")
  public void saveDispatches(@RequestBody DispatchesDTO dispatchesDTO,
      HttpServletResponse response) throws IOException {

  dispatchesService.saveDispatches(dispatchesDTO);
    success(response);
  }


@ResponseBody

直接往response中写内容而不经过视图解析器时可以使用@ResponseBody

放在方法上或者返回类型前,表示此方法返回的数据放在response body里面,而不是跳转页面。一般用于ajax请求,返回json数据。

	/**
	 * 取得商品类型<br/>
	 * @param  request 请求实例
	 * @return retMap
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "/getTypeList.htm")
	public HashMap<String, Object> getCountyList(HttpServletRequest request) throws Exception {
		HashMap<String, Object> retMap = new HashMap<String, Object>();
		List<Goods> retVal = goodsService.getTypeList(request);
		retMap.put("infoMsg", retVal);
		return retMap;
	}


@RestController

这个是Controller和ResponseBody的组合注解,表示@Controller标识的类里面的所有返回参数都放在response body里面。

@RestController =@Controller + @ResponseBody controller中方法都自带@ResponseBody 

源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

}

@PathVariable

路径绑定变量,用于绑定restful路径上的变量。

在spring MVC中,两者的作用都是将request里的参数的值绑定到contorl里的方法参数里的,区别在于,URL写法不同。
使用@RequestParam时,URL是这样的:http://host:port/path?参数名=参数值

使用@PathVariable时,URL是这样的:http://host:port/path/参数值

@RequestMapping(value="/user",method = RequestMethod.GET)  
   public @ResponseBody  
   User printUser(@RequestParam(value = "id", required = false, defaultValue = "0")  
   int id) {  
    User user = new User();  
       user = userService.getUserById(id);  
       return user;  
   }  
     
   @RequestMapping(value="/user/{id:\\d+}",method = RequestMethod.GET)  
   public @ResponseBody  
   User printUser2(@PathVariable int id) {  
       User user = new User();  
       user = userService.getUserById(id);  
       return user;  
   } 

访问路径分别是http://localhost:8080/user?id=1   和  http://localhost:8080/user/1 

PathVariable的请求路径可以被猜到。


@Transactional

注解式事务

	/**
	 * 商品编辑:根据GoodsVO的isAdd字段判断更新商品记录或新增商品记录
	 * @param GoodsVO 经销商信息
	 * @param isAdd 0 编辑,1 追加
	 * @return Integer 更新结果条目数
	 * @throws Exception
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) 
	public int editGoods(HttpServletRequest request, GoodsVO goods, String isAdd) throws Exception {
}

事物传播行为介绍: 
  @Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
  @Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务
  @Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
  @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常
  @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
  @Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.

事物超时设置:
        @Transactional(timeout=30) //默认是30秒

事务隔离级别:
  @Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读, 不可重复读) 基本不使用
  @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)
  @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)

  @Transactional(isolation = Isolation.SERIALIZABLE):串行化

  MYSQL: 默认为REPEATABLE_READ级别
  SQLSERVER: 默认为READ_COMMITTED

注意转载

1. 不要在接口上声明@Transactional ,而要在具体类的方法上使用 @Transactional 注解,否则注解可能无效。

2.不要图省事,将@Transactional放置在类级的声明中,放在类声明,会使得所有方法都有事务。故@Transactional应该放在方法级别,不需要使用事务的方法,就不要放置事务,比如查询方法。否则对性能是有影响的。

3.使用了@Transactional的方法,对同一个类里面的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。(经常在这里出错)

4.使用了@Transactional的方法,只能是public,@Transactional注解的方法都是被外部其他类调用才有效,故只能是public。道理和上面的有关联。故在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错,但事务无效。

5.经过在ICORE-CLAIM中测试,效果如下:
A.抛出受查异常XXXException,事务会回滚。
B.抛出运行时异常NullPointerException,事务会回滚。
C.Quartz中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)
D.异步任务中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)
E.在action中加上@Transactional,不会回滚。切记不要在action中加上事务。
F.在service中加上@Transactional,如果是action直接调该方法,会回滚,如果是间接调,不会回滚。(即上文3提到的)

G.在service中的private加上@Transactional,事务不会回滚。

H.spring的事务在抛异常的时候会回滚,如果是catch捕获了,事务无效。

注解中常用参数说明:

参数名称

功能描述

readOnly

该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)

rollbackFor

该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:

指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName

该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:

指定单一异常类名称:@Transactional(rollbackForClassName="RuntimeException")

指定多个异常类名称:@Transactional(rollbackForClassName={"RuntimeException","Exception"})

noRollbackFor

该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:

指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)

指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName

该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:

指定单一异常类名称:@Transactional(noRollbackForClassName="RuntimeException")

指定多个异常类名称:

@Transactional(noRollbackForClassName={"RuntimeException","Exception"})

propagation

该属性用于设置事务的传播行为,具体取值可参考表6-7。

例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

isolation

该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置

timeout

该属性用于设置事务的超时秒数,默认值为-1表示永不超时


@RequestHeader

放在方法参数前,用来获取request header中的参数值。

/@RequestHeader:获取浏览器头信息:限制请求头中必须有User-Agent
    //User-Agent:封装了浏览器的信息
    //helloMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
    @RequestMapping("show22")
    public String show22(@RequestHeader("User-Agent")String browser){
        System.out.println("hello"+browser);
        return "/index.jsp";
    }


@CookieValue

可让处理方法入参绑定某个 Cookie 值   Cookie 存在时才能取到

@RequestMapping("/springmvc")  
@Controller  
public class HelloWorld {  
@RequestMapping("/testCookieValue")  
    public String testCookieValue(@CookieValue("JSESSIONID")String sessionId){  
        System.out.println("testCookieValue: "+sessionId);  
        return "success";  
    }  
}  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值