注解-常用注解

Java注解,做个笔记。

前两天学习Spring Boot整合Redis时候写的测试类中,地址栏输入请求后页面找不到。然后就查了一下,也开始了Java注解的学习之路。

1
2
3
4
5
6
7
8
9
10
11
12
@Controller
@RequestMapping(value = "/test")
public class TestDBController {
@Autowired
private RedisUtils redisUtils;

@RequestMapping(value = "/getRedis")
public String getRedis(){
redisUtils.set("a",1);
return redisUtils.get("a").toString();
}
}

这要从@RequestMapping说起

@RequestMapping

这个注解会将 HTTP 请求映射到Control的处理方法上.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
@RequestMapping("/home")
public class IndexController{

@RequestMapping("/")
public String get(){
return "methodName IndexController.get()"
}

@RequestMapping("/index")
public String index(){
return "methodName IndexController.index()"
}

}
  • /home请求由get()方法处理,返回methodName IndexController.get()

  • /home/index请求由index()方法处理,返回methodName IndexController.index()

基本上是我接触到的第一个注解了。

还可以指定一个多个请求指向一个处理方法

1
2
3
4
5
6
7
8
9
10
@RestController
@RequestMapping("/home")
public class IndexController{

@RequestMapping(value = {"","/page","all"})
public String get(){
return "methodName IndexController.get()"
}

}

/home,/home/page./home/all都由get()方法处理。

@RequestMapping还可以指定请求方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
@RequestMapping("/home")
public class IndexController{

@RequestMapping()
public String get(){
return "methodName IndexController.get()"
}

@RequestMapping(method = RequestMethod.POST)
public String post(){
return "methodName IndexController.post()"
}

}

默认的请求都是get,指定请求方式时跳转对应的处理方法处理方法,使用post请求/home时返回methodName IndexController.post().

常用功能先到这里吧,但是我不禁陷入了沉思,还有很多用法,在现在的项目里用不到,我到底要不要整理,不整理,就感觉学的不透彻(虽然整理了还是会忘掉)。可是整理吧,就是个蚂蚁窝,可能把整个草原都翻一遍。时间太长,用不到就是在做无用功。希望有过这种经历,并有想法的可以通过右下角告诉我。

@RequsetParam

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
@RequestMapping("/home")
public class IndexController{

@RequestMapping("/getParamByName")
public String getParamByName(@RequestParam(value="name",defaultValue="2") String id){
return id;
}

@RequestMapping("/getParamById")
public String getParamById(@RequestParam() String id){
return id;
}

}

@RequestParam将请求参数绑定到处理方法的形参上。

  • /home/getParamByName?name=1,页面返回1,如果请求的时候没带参数将使用默认值2。
  • /home/getParamById?id=2,页面返回2.如果请求参数和形参同名情况下可以省略注解内的名称。其实,同名情况可以将@RequestParam都省略掉。

@ResponseBody

@Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上@Responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。

这就到了一开始说到了为什么类用了@Controller注释再用@RequestMapping返回字符串显示找不到页面的情况了。

可以给方法加上@ResponseBody或者将@Controller换成@RestController

原来返回指定页面的也会因为使用了@RestController而显示路径名。

说道ResponseBody不说RequestBody有点对不住他

@RequestBody

Get请求没有请求体,要使用@RequestBody可以用post提交请求。

一个请求请求只有一个@RequestBody,一个请求可以有多个@RequestParam

1
2
3
4
5
6
@RequestMapping("/testRequestParam")
public void requestParam(User user ,@RequestParam Integer userId,
@RequestParam String userName,@RequestParam String password,@RequestParam String phone){
System.out.println("userId=" + userId + "userName=" + userName + "password=" + password + "phone="+ phone);
System.out.println(user.toString());
}

userId=1userName=2password=3phone=4
User(userId=1, userName=2, password=3, phone=4)

GET使用x-www-form-urlencoded会报错

{
“timestamp”: “2019-07-11T10:42:03.750+0000”,
“status”: 400,
“error”: “Bad Request”,
“message”: “Required Integer parameter ‘userId’ is not present”,
“path”: “/test/testRequestBody”
}

POST请求下@RequestParam获取使用x-www-form-urlencoded返回结果与GET请求使用form-data相同

但是如果想批量传参,就需要用到RequestBody

1
2
3
4
5
6
@RequestMapping("/testRequestBody")
public void requestBody(@RequestBody List<User> userList){
for (User user :userList){
System.out.println(user.toString());
}
}

console:

User(userId=1, userName=2, password=3, phone=4)
User(userId=5, userName=6, password=7, phone=8)

@Resource和@Autowired

spring扫描自动命名机制-将类的首字母小写当做name。

bean有两个重要属性,名称(id)类型(class )

@Resource和@Autowired都是用来注入bean的。但两者有一些不同。

@Resource

@Resource并不是Spring的默认注解,需要导入javax.annotation.Resource包使用。

@Resource有两个属性:nametype,可以注解属性和setter方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Class UserManager{
@Resource(name="userDao")
private UserDao userDao;

}


public Class UserManager{
private UserDao userDao;

@Resource(name="userDao")
public void setUserDao(UserDap userDao){
this.UserDao = userDao;
}
}

@Resource装配顺序:

  1. 如果同时指定了nametype,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
  3. 如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常
  4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。

@Autowired

@Autowired只会按照type进行注入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class UserManager {
@Autowired
private UserDao userDao;

}


public class UserManager {
private UserDao userDao;

@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}

@Autowired注入,默认要求被注入的bean是存在的,如果允许为null,则可以将它的required属性置为false

如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。

1
2
3
4
5
public class UserManager {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}

@Autowired默认先按byType进行匹配,如果发现找到多个bean,则又按照byName方式进行匹配,如果还有多个,则报出异常。