七、注册-业务层
7.1规划异常
7.1.1用户在进行注册的时候,可能会产生用户名被占用的错误,抛出一个异常;
RuntimeException异常,作为该异常的子类,然后再去定义具体的异常类型继承这个异常。
写一个业务层异常的基类,ServiceException异常,这个异常继承RuntimeException异常。
package com.example.store.service.ex; /** * @Description:业务层异常的基类 throws new ServiceException("业务层产生未知的异常") * @Author: * @Date: */ public class ServiceException extends RuntimeException{ public ServiceException() { super(); } public ServiceException(String message) { super(message); } public ServiceException(String message, Throwable cause) { super(message, cause); } public ServiceException(Throwable cause) { super(cause); } protected ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
根据业务层不同的功能来详细定义具体的异常类型,统一的去继承ServiceException异常类。
7.1.2用户在注册的时候可能会产生用户名被占用的错误,抛出一个异常:UsernameDuplicatedException异常
public class UsernameDuplicatedException extends ServiceException{ public UsernameDuplicatedException() { super(); } public UsernameDuplicatedException(String message) { super(message); } public UsernameDuplicatedException(String message, Throwable cause) { super(message, cause); } public UsernameDuplicatedException(Throwable cause) { super(cause); } protected UsernameDuplicatedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
7.1.3正在执行数据插入操作的时候,服务器、数据库宕机。处于正在执行插入操作过程中所产生的异常:
InsertException异常。
public class InsertException extends ServiceException { public InsertException() { super(); } public InsertException(String message) { super(message); } public InsertException(String message, Throwable cause) { super(message, cause); } public InsertException(Throwable cause) { super(cause); } protected InsertException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
7.2设计接口和抽象方法
7.2.1在service包下创建一个IUserService
/**用户模块业务层接口**/ public interface IUserService { /** *用户注册方法 * @param user用户的数据对象 */ void reg(User user); }
7.2.2创建一个实现类UserServiceImpl类,需要实现这个接口,并且实现抽象方法。
7.2.3在单元测试包下创建一个UserServiceTests类,在这个类中添加单元测试的功能。
八、注册-控制层
8.1创建响应
状态码,状态描述信息,数据。这部分功能封装在一个类中,将这个类作为方法返回值,返回给前端浏览器。
/** * @Description:Json格式的数据进行响应 * @Author: * @Date: */ @Data @NoArgsConstructor @AllArgsConstructor public class JsonResult<E> implements Serializable {//Serializable接口 /**状态码*/ private Integer state; /**描述信息*/ private String message; /**泛型数据*/ private E data; }
8.2 设计请求
依据当前的业务功能模块进行请求的设计。
请求路径:/user/reg
请求参数:user user
请求类型:POST(有敏感数据就用POST,没有就用get)
响应结果:JsonResult
8.3处理请求
8.3.1创建一个控制层对应的类UserController类。依赖于业务层的接口。
package com.example.store.controller; import org.springframework.stereotype.Controller; import com.example.store.entity.User; import com.example.store.service.IUserService; import com.example.store.service.ex.InsertException; import com.example.store.service.ex.UsernameDuplicatedException; import com.example.store.util.JsonResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /** * @Description: * @Author: * @Date: */ //@Controller //当前类交给Spring来管理、 @RestController//等效于@Controller+@ResponseBody @RequestMapping("/users") public class UserController { @Autowired private IUserService userService;//依赖于业务层的接口,即userService接口,然后交给Spring自动装配,最后什么样的请求被拦截在子类当中呢。 @RequestMapping("/reg") //@ResponseBody //表示此方法的响应结果以json格式进行数据的响应给到前端 //如果在这个类中编写了大量的请求处理方法,也就意味着每个类中都要编写一个ResponseBody,是很麻烦的,所以并不建议这样写,这里写组合注解 public JsonResult<Void> reg(User user){ //声明一个User对象,作为方法的参数列表,来接收前端的数据 //创建响应结果对象 JsonResult<Void> result = new JsonResult<>(); try { userService.reg(user);//在调这个方法的时候,如果抛异常,在Code里面点Surround With 的try/catch result.setState(200); result.setMessage("用户名注册成功"); } catch (UsernameDuplicatedException e) { //抛的异常即我们在业务层所定义的异常,这里是两个 result.setState(4000); result.setMessage("用户名被占用"); } catch (InsertException e) { //抛的异常即我们在业务层所定义的异常,这里是两个 result.setState(5000); result.setMessage("注册时产生未知的异常"); } return result; } }
8.4 控制层优化设计
在控制层抽离一个父类,在这个父类中统一的去处理关于异常的相关操作。编写一个BaseController类,统一处理异常。
重新构建了reg()方法。
package com.example.store.controller; import org.springframework.stereotype.Controller; import com.example.store.entity.User; import com.example.store.service.IUserService; import com.example.store.service.ex.InsertException; import com.example.store.service.ex.UsernameDuplicatedException; import com.example.store.util.JsonResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /** * @Description: * @Author: * @Date: */ //@Controller //当前类交给Spring来管理、 @RestController//等效于@Controller+@ResponseBody @RequestMapping("/users") public class UserController extends BaseController{ @Autowired private IUserService userService;//依赖于业务层的接口,即userService接口,然后交给Spring自动装配,最后什么样的请求被拦截在子类当中呢。 @RequestMapping("/reg") //@ResponseBody //表示此方法的响应结果以json格式进行数据的响应给到前端 //如果在这个类中编写了大量的请求处理方法,也就意味着每个类中都要编写一个ResponseBody,是很麻烦的,所以并不建议这样写,这里写组合注解 public JsonResult<Void> reg(User user){ //声明一个User对象,作为方法的参数列表,来接收前端的数据 userService.reg(user); return new JsonResult<>(OK); }
👆此为UserController类
👇此为BaseController类
package com.example.store.controller; import com.example.store.service.ex.InsertException; import com.example.store.service.ex.ServiceException; import com.example.store.service.ex.UsernameDuplicatedException; import com.example.store.util.JsonResult; import org.springframework.web.bind.annotation.ExceptionHandler; /** * @Description:控制层的基类 * @Author: * @Date: */ public class BaseController { /**操作成功的状态码**/ public static final int OK =200; //请求处理方法,这个方法的返回值就是需要传递给全端的数据 //自动将异常对象传递给此方法的参数列表上 //当前项目中产生了异常,被统一拦截到此方法中,这个方法此时就充当的是请求处理方法,方法的返回值直接给到前端 @ExceptionHandler(ServiceException.class)//用于统一处理抛出的异常 public JsonResult<Void> handleException(Throwable e){ JsonResult<Void> result = new JsonResult<>(e); if(e instanceof UsernameDuplicatedException){ result.setState(400); result.setMessage("用户名已经被占用"); } else if(e instanceof InsertException){ result.setState(5000); result.setMessage("注册时产生了未知的异常"); } return result; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端