1、Controller層
controller層在MVC設計中屬於控制層;設計初衷:接受請求並響應請求;所以,該層盡量輕薄,避免編寫涉及業務處理的代碼。
前后端分離的開發設計模式下,推薦使用@RestController注解,它相當於@ResponseBody + @Controller的組合使用。
- 如果只是使用@RestController注解Controller類,則Controller中的方法無法返回jsp頁面,或者html,配置的視圖解析器InternalResourceViewResolver不起作用,返回的內容就是Return 里的內容,默認轉成json串。
- 如果需要返回到指定頁面,則需要用 @Controller配合視圖解析器InternalResourceViewResolver才行。 如果需要返回JSON,XML或自定義mediaType內容到頁面,則需要在對應的方法上加上@ResponseBody注解。
總之,使用@Controller 注解,在對應的方法上,視圖解析器可以解析return 的jsp,html頁面,並且跳轉到相應頁面;若返回json等內容到頁面,則需要加@ResponseBody注解,ResponsesBean 是Controller專用的,是不允許往后傳。
1.1 設定請求路徑
使用注解@PostMapping("/page"),類命名和方法命名之上都可以加。
注意按照不同業務進行划分使用,避免亂寫亂用。
1.2 設置請求方式
常用的POST/GET。使用注解:@RequestMapping 和 @GetMapping @PostMapping。
Spring4.3中引進了{@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping} 來幫助簡化常用的HTTP方法的映射 並更好地表達被注解方法的語義
該注解將HTTP Get 映射到 特定的處理方法上
@GetMapping是一個組合注解,它是@RequestMapping(method = RequestMethod.GET)的縮寫
@PostMapping是一個組合注解,它是@RequestMapping(method = RequestMethod.POST)的縮寫
1.3 設置請求參數方式
①表單提交,直接使用vo類或具體參數名接收;
@Controller
public class LoginController {
@RequestMapping(value = "login", method = RequestMethod.POST)
public String login(UserVO user){
System.out.println("POJO: " + user.getClass().getName() +
", hash code: " + user.hashCode() + ", " + user.toString());
return "redirect:/";
}
}
②@RequestParam
@RequestParam(value="", required=true, defaultValue="")
@RequestParam 有三個屬性:
(1)value:請求參數名(必須配置)
(2)required:是否必需,默認為 true,即 請求中必須包含該參數,如果沒有包含,將會拋出異常(可選配置)
(3)defaultValue:默認值,如果設置了該值,required 將自動設為 false
@ApiOperation(value = "根據id查詢")
@PostMapping("/show")
public Responses show(@RequestParam(value="userId",defaultValue="-1") Long userId) {
Record data = recordService.getOne(vo.getId());
return Responses.success(data);
}
③提交,使用注解@RequestBody。
@RequestBody主要用來接收前端以POST方式傳遞給后端的json字符串中的數據的(請求體中的數據的);GET方式無請求體,所以使用@RequestBody接收數據時,前端不能使用GET方式提交數據,而是用POST方式進行提交。在后端的同一個接收方法里,@RequestBody與@RequestParam()可以同時使用,@RequestBody最多只能有一個,而@RequestParam()可以有多個。
注:一個請求,只有一個RequestBody;一個請求,可以有多個RequestParam。
@ApiOperation(value = "根據id查詢")
@PostMapping("/get")
public Responses getOne(@Validated @RequestBody IdVO vo){
Record data = recordService.getOne(vo.getId());
return Responses.success(data);
}
④PathVariable
@RestController
@RequestMapping("/")
public class ChineseDrugController {
@ResponseBody
@RequestMapping(value = "/{name}")
public String showName(@PathVariable String name, @PathVariable(value = "name", required = false) String sex) {
return "Hello " + name + sex;
}
⑤@PathParam
url:http://127.0.0.1:8080/sexvalue/namevalue?name=劉&sex=男
@RestController
@RequestMapping(value = "/{sex}")
public class ChineseDrugController {
@ResponseBody
@RequestMapping(value = "/{name}")
public String showName(@PathVariable(value = "name") String name, @PathParam(value = "sex") String sex) {
return "Hello " + name + " " + sex;
}
}
說明:以上代碼僅僅展示功能上有很好的靈活性,實際開發中避免如此任意使用 。
1.4 校驗請求參數
參數校驗
①使用注解@Validated,使得參數自動校驗生效,它是spring-contex中的注解;
②vo類中自定義各類校驗,比如@NotNull等,他是javax下validation-api中的注解此處不贅述;
③程序層面的校驗。
方法示例如下
@ApiOperation(value = "應用類型和應用關系綁定")
@PostMapping("/applicationTypeBind")
public Boolean applicationTypeBind(@Validated @RequestBody ApplicationBindVO vo){
applicationTypeService.applicationTypeBind(vo);
return true;
}
對應VO類示例
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;
@Data
@ApiModel(value = "ApplicationBindVO",description = "關系綁定vo")
public class ApplicationBindVO {
@NotNull
@ApiModelProperty("應用類型id")
private Long typeId;
@ApiModelProperty("應用id集合")
private List<Long> applicationIdList;
}
1.5 入參出參設計
依據業務而定,格式盡量做到統一;
響應前端(APP/PC)的參數,一般再封裝一層,方便前端統一處理,如下返回
Responses.success(data);
import com.fasterxml.jackson.annotation.JsonView;
import com.myfutech.common.util.enums.ResponseCode;
import com.myfutech.common.util.vo.BaseView;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "Responses",description = "響應信息")
public class Responses<T> {
@JsonView({BaseView.class})
@ApiModelProperty("響應編碼")
private String code;
@JsonView({BaseView.class})
@ApiModelProperty("響應消息")
private String msg;
@JsonView({BaseView.class})
@ApiModelProperty("響應體")
private T result;
public static <T> Responses<T> success() {
return new Responses(ResponseCode.SUCCESS_CODE, "", (Object)null);
}
public static <T> Responses<T> success(T result) {
return new Responses(ResponseCode.SUCCESS_CODE, "", result);
}
public static <T> Responses<T> success(String msg, T result) {
return new Responses(ResponseCode.SUCCESS_CODE, msg, result);
}
public static <T> Responses<T> error(String msg) {
return new Responses(ResponseCode.ERROR_CODE, msg, (Object)null);
}
public static <T> Responses<T> error(ResponseCode code) {
return new Responses(code, code.getDefaultMsg(), (Object)null);
}
public static <T> Responses<T> error(ResponseCode code, String msg) {
return new Responses(code, msg, (Object)null);
}
public Responses() {
}
private Responses(ResponseCode code, String msg, T result) {
this.code = code.getCode();
this.msg = msg;
this.result = result;
}
public String getCode() {
return this.code;
}
public boolean notSuccess() {
return !ResponseCode.SUCCESS_CODE.getCode().equals(this.code);
}
public String getMsg() {
return this.msg;
}
public T getResult() {
return this.result;
}
public void setCode(String code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setResult(T result) {
this.result = result;
}
}
1.6 自動生成接口文檔
使用SwaggerAPI,
常用注解
//加載類名之上
@Api(tags = "日志相關接口", description="操作日志",
consumes= MediaType.APPLICATION_JSON_UTF8_VALUE,
produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
//加在方法名之上
@ApiOperation(value = "查詢分頁列表")
//加載實體或VO類名之上
@Data
@ApiModel(value = "ApprovalRoleModifyVO",description = "審批角色修改信息")
public class ApprovalRoleModifyVO{
- @Api:作用在類上,用來標注該類具體實現內容。表示標識這個類是swagger的資源 。
參數:
①tags:可以使用tags()允許您為操作設置多個標簽的屬性,而不是使用該屬性。
②description:可描述描述該類作用。
-
@ApiOperation:用於方法,表示一個http請求的操作 。
-
@ApiModel:用於方法,字段 ,表示對model屬性的說明或者數據操作更改
2一個相對標准controller類示例
package com.myfutech.employee.service.provider.ctrl;
import com.myfutech.common.util.Responses;
import com.myfutech.common.util.vo.IdVO;
import com.myfutech.common.util.vo.Page;
import com.myfutech.common.util.vo.Pageable;
import com.myfutech.employee.service.api.vo.response.record.RecordListVo;
import com.myfutech.employee.service.provider.model.Record;
import com.myfutech.employee.service.provider.service.RecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 相關接口
*/
@Api(tags = "日志相關接口", description="操作日志",
consumes= MediaType.APPLICATION_JSON_UTF8_VALUE,
produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
@RestController
@RequestMapping("/record")
public class RecordCtrl {
private static final Logger log = LoggerFactory.getLogger(RecordCtrl.class);
@Resource(name="recordService")
private RecordService recordService;
@ApiOperation(value = "查詢分頁列表")
@PostMapping("/page")
public Page<RecordListVo> page( @RequestBody Pageable pageable){
Page<RecordListVo> list = recordService.findConditionPage(pageable);
return list;
}
@ApiOperation(value = "根據id查詢")
@PostMapping("/get")
public Responses queryById(@Validated @RequestBody IdVO vo){
Record data = recordService.getOne(vo.getId());
return Responses.success(data);
}
@ApiOperation(value = "新增")
@PostMapping("/add")
public Responses add(@Validated(Record.Create.class) @RequestBody Record data){
recordService.save(data);
return Responses.success();
}
@ApiOperation(value = "更新")
@PostMapping("/update")
public Responses update(@Validated(Record.Update.class) @RequestBody Record data){
recordService.save(data);
return Responses.success();
}
@ApiOperation(value = "刪除")
@PostMapping("/delete")
public Responses delete(@Validated @RequestBody IdVO vo){
recordService.deleteById(vo.getId());
return Responses.success();
}
}