4. 使用 SpringMVC 实现 Restful 接口
org.seckill > web
SeckillController
Controller 层的作用:C -> 控制层,职责为接收参数,根据一些验证和判断帮助我们做跳转的控制,如果不符合要求跳转到列表页,符合则跳转到 detail 页
package org.seckill.web;
import org.seckill.dto.Exposer;
import org.seckill.dto.SeckillExecution;
import org.seckill.dto.SeckillResult;
import org.seckill.entity.Seckill;
import org.seckill.enums.SeckillStateEnum;
import org.seckill.exception.RepeatKillException;
import org.seckill.exception.SeckillCloseException;
import org.seckill.service.SeckillService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
/**
* Created by dixinkk on 2022/01/09.
*/
@Controller // 把SeckillController 放到 Spring 容器中
@RequestMapping("/seckill") // url: /模块/资源/{id}/细分 --/seckill/list
public class SeckillController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private SeckillService seckillService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String list(Model model) {
// 获取列表页
List<Seckill> list = seckillService.getSeckillList();
model.addAttribute("list", list);
// list.jsp + model = ModelAndView
return "list"; // /WEB-INF/jsp/"list".jsp
}
@RequestMapping(value = "/{seckillId}/detail", method = RequestMethod.GET)
public String detail(@PathVariable("seckillId") Long seckillId, Model model) {
if(seckillId == null) {
return "redirect:/seckill/list";
}
Seckill seckill = seckillService.getById(seckillId);
if(seckill == null) {
return "forward:/seckill/list";
}
model.addAttribute("seckill", seckill);
return "detail";
}
// ajax json
@RequestMapping(value = "/{seckillId}/exposer",
method = RequestMethod.POST,
produces = {"application/json; charset=UTF-8"})
@ResponseBody // SpringMVC 看到这个注解时 会把返回的数据类型封装成 json
public SeckillResult<Exposer> exposer(Long seckillId) {
SeckillResult<Exposer> result;
try {
Exposer exposer = seckillService.exportSeckillUrl(seckillId);
result = new SeckillResult<Exposer>(true, exposer);
} catch (Exception e) {
logger.error(e.getMessage(), e);
result = new SeckillResult<Exposer>(false, e.getMessage());
}
return result;
}
@RequestMapping(value = "/{seckillId}/{md5}/execution",
method = RequestMethod.POST,
produces = {"application/json; charset=UTF-8"})
@ResponseBody
public SeckillResult<SeckillExecution> execute(@PathVariable("seckillId") Long seckillId,
@PathVariable("md5") String md5,
@CookieValue(value = "killPhone", required = false) Long userPhone) {
// SpringMVC valid
if(userPhone == null) {
return new SeckillResult<SeckillExecution>(false, "未注册");
}
SeckillResult<SeckillExecution> result;
try {
SeckillExecution execution = seckillService.executeSeckill(seckillId, userPhone, md5);
return new SeckillResult<SeckillExecution>(true, execution);
} catch (RepeatKillException e) {
SeckillExecution execution = new SeckillExecution(seckillId, SeckillStateEnum.REPEAT_KILL);
return new SeckillResult<SeckillExecution>(false, execution);
} catch (SeckillCloseException e) {
SeckillExecution execution = new SeckillExecution(seckillId, SeckillStateEnum.END);
return new SeckillResult<SeckillExecution>(false, execution);
} catch (Exception e) {
logger.error(e.getMessage(), e);
SeckillExecution execution = new SeckillExecution(seckillId, SeckillStateEnum.INNER_ERROR);
return new SeckillResult<SeckillExecution>(false, execution);
}
}
@RequestMapping(value = "/time/now", method = RequestMethod.GET)
public SeckillResult<Long> time() {
Date now = new Date();
return new SeckillResult(true, now.getTime());
}
}
dto > SeckillResult
package org.seckill.dto;
/**
* 所有 ajax 请求返回类型,封装 json 结果
* Created by dixinkk on 2022/01/09.
*/
public class SeckillResult<T> {
private boolean success;
private T data;
private String error;
public SeckillResult(boolean success, T data) {
this.success = success;
this.data = data;
}
public SeckillResult(boolean success, String error) {
this.success = success;
this.error = error;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
5. 基于 bootstrap 开发页面结构
Bootstrap 菜鸟教程 https://www.runoob.com/bootstrap/bootstrap-tutorial.html
https://github.com/codingXiaxw/seckill/tree/master/src
https://gitee.com/dixin9869