現将
Spring MVC
中常用注解的使用整理如下.
@Controller
@Controller
@Controller
注解可以标記一個類, 指明該類是一個控制器(Controller).
要想使
Spring
能夠識别出使用
@Controller
标記的類使一個控制器, 還需要進行相應的配置, 有兩種配置方式:
1、在
Spring MVC
的配置檔案中定義一個
MyController(這是我們自定義的控制器,用@Controller标記)
的
bean
對象.
<bean class="com.tao.myapp.web.controller.MyController"/>
2、 在
Spring MVC
的配置檔案中開啟注解自動掃描, 讓
Spring
自動的去指定的包下面掃描
@Controller
注解的類.
<context:component-scan base-package="com.tao.myapp.web.controller"/>
context:component-scan
預設掃描的注解類型是
@Component
, 不過, 在
@Component
語義基礎上細化後的
@Repository
,
@Service
和
@Controller
也同樣可以被
context:component-scan
掃描識别.
@Component
@Component
這個注解是一個通用的注解, 表示
Spring
中的一個元件, 當我們不太清楚一個類要歸到哪個層的元件中去的時候,可以使用這個注解, 不過通常
不建議使用
.
@Repository
@Repository
這個注解用于
dao
層, 通常注解到
daoImpl
類上面.
@RequestMapping
@RequestMapping
這個注解是一個用來處理請求位址映射的注解, 可用于類或方法上. 用于類上, 表示類中的所有響應請求的方法都是以該位址作為父路徑; 用于方法上, 表示特定而url請求将會被該方法處理.
@RequestMapping
的屬性如下:
1、
value
和
method
- value: 指定請求的
路徑. 在使用的時候url
字段可以省略,value
用引号括起來.url
還支援通配符value
和"*"
."**"
@Controller
@RequestMapping("/myapp")
public class MyController {
/** 可以通過 http://localhost:8080/myapp/haha/test 通路 */
@RequestMapping("*/test")
public String test() {
System. out .println( "-----myapp test-----" );
return "test" ;
}
}
- method: 指定請求的
類型,method
、GET
、POST
、PUT
等. 也可以通過DELETE
、@GetMapping
等注解替換.@PostMapping
@RequestMapping(value = "/testMethod" , method = {RequestMethod.GET, RequestMethod.DELETE})
public String testMethod() {
return "method";
}
2、
consumes
和
produces
- consumes: 指定請求的送出的内容的類型(
), 例如Content-Type
,application/json
.text/html
- produces: 指定傳回的内容類型, 僅當
請求頭中的(request
)類型中包含該指定類型才傳回.Accept
3、
params
和
headers
- params: 指定
中必須包含某些參數值時, 才讓該方法處理.request
@RequestMapping(value = "/testParams", params = {"param1=value1", "param2", "!param3"})
public String testParams() {
System.out.println("-----------test Params-----------");
return "testParams";
}
如上例所示,
params
屬性指定了三個參數, 這些參數都是針對請求參數而言的, 它們分别表示參數
param1
的值必須等于
value1
; 參數
param2
必須存在, 值無所謂; 參數
param3
必須不存在. 隻有當請求
/testParams
并且滿足指定的三個參數條件的時候才能通路到該方法. 是以當請求
/testParams?param1=value1¶m2=value2
的時候能夠正确通路到該
testParams()
方法, 當請求
/testParams?param1=value1¶m2=value2¶m3=value3
的時候就不能夠正常的通路到該方法. 因為在
params
參數裡面指定了參數
param3
是不能存在的.
- headers: 指定
中必須包含某些指定的request
值, 才能讓該方法處理請求.header
@RequestMapping(value = "/testHeaders" , headers = {"host=localhost" ,"Accept"})
public String testHeaders() {
return "headers";
}
headers
屬性的用法和功能與
params
屬性相似.
在上面的代碼中當請求
/testHeaders
的時候, 隻有當請求頭包含
Accept
資訊, 且請求的
host
為
localhost
的時候才能正确的通路到
testHeaders()
方法.
@Resource
和 @Autowired
@Resource
@Autowired
@Resource
和
@Autowired
都是做
bean
的注入時使用.
@Resource
不是
Spring
的注解, 它的包是
javax.annotation.Resource
.
兩者都可以寫在字段和setter方法上. 兩者如果都寫在字段上, 那麼就不需要再寫setter方法.
1、
@Autowired
@Autowired
是
Spring
提供的注解, 所在的包為
org.springframework.beans.factory.annotation.Autowired
.
@Autowired
注解是按照類型(
byType
) 裝配依賴對象的, 預設情況下它要求依賴對象必須存在, 如果允許null值, 可以設定它的
required
屬性為
false
. 如果我們想使用按照名稱(
byName
) 來裝配, 可以結合
@Qualifier
注解一起使用.
2、
@Resource
@Resource
預設按照名稱(
byName
) 來自動注入.
@Resource
有兩個重要的屬性:
name
和
type
.
Spring
将
@Resource
注解的
name
屬性解析為
bean
的名字, 而
type
屬性則解析為
bean
的類型. 是以, 如果使用
name
屬性, 則使用
byName
的自動注入政策; 而使用
type
屬性時則使用
byType
自動注入政策. 如果既不指定
name
也不指定
type
屬性, 這時将通過反射機制使用
byName
自動注入政策.
最好是将放在
@Resource
方法上, 因為這樣更符合面向對象的思想, 通過
setter
、
set
去操作屬性, 而不是直接去操作屬性.
get
@Resource
的作用相當于
@Autowired
, 隻不過
@Autowired
預設是按照
byType
自動注入.
@PathVariable
@PathVariable
這個注解用于将請求
url
中的模闆變量映射到處理方法的參數上, 也就是說從請求的路徑上取出需要的參數.
@Controller
public class TestController {
@RequestMapping(value = "/user/{userId}/roles/{roleId}", method = RequestMethod.GET)
public String getLogin(
@PathVariable("userId") String userId,
@PathVariable("roleId") String roleId) {
System.out.println("User Id : " + userId);
System.out.println("Role Id : " + roleId);
return "hello";
}
@RequestMapping(value = "/javabeat/{regexp1:[a-z-]+}", method = RequestMethod.GET)
public String getRegExp(@PathVariable("regexp1") String regexp1) {
System.out.println("URI Part 1 : " + regexp1);
return "hello";
}
}
@Controller
@RequestMapping("/test/{variable1}")
public class MyController {
@RequestMapping("/showView/{variable2}")
public ModelAndView showView(
@PathVariable("variable1") String variable1,
@PathVariable("variable2") int variable2) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("viewName");
modelAndView.addObject("需要放到 model 中的屬性名稱", "對應的屬性值,它是一個對象");
return modelAndView;
}
}
@RequestHeader
@RequestHeader
這個注解可以将
Request
請求(
HTTP請求
)中的
header
請求頭部分的屬性值綁定到處理方法的參數上.
Host localhost:
Accept text/html,application/xhtml+xml,application/xml;q=
Accept-Language fr,en-gb;q=,en;q=
Accept-Encoding gzip,deflate
Accept-Charset ISO--,utf-;q=,*;q=
Keep-Alive
@RequestMapping("/displayHeaderInfo")
public void displayHeaderInfo(
@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) {
System.out.println("Accept-Encoding : " + encoding);
System.out.println("Keep-Alive : " + keepAlive);
}
上面的代碼, 通過使用
@RequestHeader
把
header
部分的
Accept-Encoding
的值綁定到參數
encoding
上了; 把
Keep-Alive
的值綁定到參數
keepAlive
上了.
@CookieValue
@CookieValue
這個注解可以将
Request
請求(
HTTP請求
)的
header
頭部資訊中關于
Cookie
的值綁定到方法的參數上.
假設有如下
Cookie
值:
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
@RequestMapping("/displayHeaderInfo")
public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) {
System.out.println("Cookie : " + cookie);
}
@RequestParam
@RequestParam
這個注解主要用于在
Spring MVC
背景控制層擷取請求參數.
通常在
Controller
中擷取請求參數有兩種方法:
1. request.getParameter(“參數名”)
2. 使用
注解
@RequestParam
@RequestParam
有三個常用參數:
value = “isApp”, required = false, defaultValue = “0”
-
: 參數名字, 即前端傳入的請求中參數的名字.value
-
: 是否必須, 預設是true, 表示請求中一定要有相應的參數, 否則将報404錯誤碼.required
-
: 參數的預設值, 表示如果請求中沒有同名參數時的預設值, 預設值可以是SpEL表達式, 如“defaultValue
”.#{systemProperties['java.vm.version']}
假設請求的url為
localhost:8080/myapp/test/?userName=zhangsan
@GetMapping("/requestParm")
public void getRequestParm(@RequestParam(value = "username", required = false, defaultValue = "admin") String username) {
System.out.println("username : " + username);
}
注意: 如果設定了的值, 它将預設的設定
defaultValue
的值為
required
.
false
@RequestBody
@RequestBody
這個注解用于将
Controller
的方法參數, 根據
HTTP Request Header
的
Content-Type
的内容, 通過适當的
HttpMessageConverter
轉換為
Java
類.
當
POST
或者
PUT
的資料是
JSON
格式或者
XML
格式, 而不是普通的鍵值對形式的時候使用這個注解.
@RequestMapping(value = "/testRequestBody", method = RequestMethod.POST)
@ResponseBody
public Person testRequestBody(@RequestBody Person p) {
System.out.println("creating a person : " + p);
return p;
}
對應的前端
ajax
請求:
$.ajax({
url: "testRequestBody",
data: '{"name":"小紅","age":12}', //要用雙引号!!
contentType: "application/json;charset=utf-8", // 因為上面是json資料
type: "POST",
headers: {
// Accept: "application/xml",
Accept: "application/json",
},
success: function (data, textStatus) {
console.log(data);
alert(data);
},
error: function (data, textStatus, errorThrown) {
console.log(data);
},
});
@ResponseBody
@ResponseBody
該注解用于将
Controller
的方法傳回的對象, 根據
HTTP Request Header
的
Accept
的内容, 通過适當的
HttpMessageConverter
轉換為指定格式後, 寫入到
Response
對象的
body
資料區.
當傳回的資料不是
html
标簽的頁面, 而是其他某種格式的資料時( 如
json
、
xml
等 )使用.
@ExceptionHandler
@ExceptionHandler
注解到方法上,出現異常時會執行該方法.
@ControllerAdvice
@ControllerAdvice
這個注解能夠使一個
Contoller
成為全局的異常處理類, 類中用
@ExceptionHandler
注解的方法可以處理所有
Controller
發生的異常.
@ControllerAdvice
public class GlobalExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(getClass());
@ExceptionHandler(BusinessException.class)
@ResponseBody
public ResponseMsg businessError(BusinessException exception) {
logger.info("Request raised a BusinessException, business code is {}", exception.getCode());
return new ResponseMsg(exception.getCode(), exception.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseMsg sysError(Exception exception) {
String msg = "出錯了";
if(exception instanceof MaxUploadSizeExceededException) {
msg = "上傳檔案過大";
}
//exception.printStackTrace();
logger.error("Request raised " + exception.getClass().getSimpleName(), exception);
return new ResponseMsg(GeneralConst.SYS_ERROR, msg);
}
}
@InitBinder
@InitBinder
使用
@InitBinder
來處理Date類型的參數.
//the parameter was converted in initBinder
@RequestMapping("/date")
public String date(Date date) {
System.out.println(date);
return "hello";
}
//At the time of initialization,convert the type "String" to type "date"
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
參考:
https://blog.csdn.net/chenpeng19910926/article/details/70837756