【SpringBoot + Vue 尚庭公寓实战】标签管理接口优化(四)

1.标签管理

标签管理共有三个接口,分别是[根据类型]查询标签列表保存或更新标签信息根据ID删除标签,下面逐一实现。

首先在LabelController中注入LabelInfoService依赖,如下

@Tag(name = "标签管理")
@RestController
@RequestMapping("/admin/label")
public class LabelController {

    @Autowired
    private LabelInfoService service;
}

 1.1@RestController

(1) @RestController组合注解,等同于 @Controller 和 @ResponseBody 的结合使用,常用于编写 RESTful 风格的 Web 服务;

(2) @Controller:用于标记控制层(Controller),表示这是 MVC 架构中的控制器组件。Spring 会自动扫描使用了 @Controller 注解的类,并将其注册为控制器 Bean,在处理请求时自动将请求映射到相应的 @RequestMapping 注解标注的方法中进行处理。

1.2@RequestMapping

@RequestMapping注解是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上。 

2. [根据类型]查询标签列表

LabelController中增加如下内容

@Operation(summary = "(根据类型)查询标签列表")
@GetMapping("list")
public Result<List<LabelInfo>> labelList(@RequestParam(required = false) ItemType type) {

    LambdaQueryWrapper<LabelInfo> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(type != null, LabelInfo::getType, type);
    List<LabelInfo> list = service.list(queryWrapper);
    return Result.ok(list);
}

2.1@Operation

@Operation(v3)接口注释

 @Operation(summary = " ", description = " ")

2.2@GetMapping

@GetMapping注解可以用于类和方法上,用于定义HTTP GET请求的URL路径。当客户端发送HTTP GET请求时,Spring Boot会自动将请求映射到具有相应URL路径的控制器方法上。 

2.3WebDataBinder枚举类型转换

WebDataBinder依赖于Converter实现类型转换,若Controller方法声明的@RequestParam参数的类型不是StringWebDataBinder就会自动进行数据类型转换。SpringMVC提供了常用类型的转换器,例如StringIntegerStringDateStringBoolean等等,其中也包括String到枚举类型,但是String到枚举类型的默认转换规则是根据实例名称("APARTMENT")转换为枚举对象实例(ItemType.APARTMENT)。若想实现code属性到枚举对象实例的转换,需要自定义Converter,代码如下,具体内容可参考官方文档

(1)在web-admin模块自定义com.atguigu.lease.web.admin.custom.converter.StringToItemTypeConverter

@Component
public class StringToItemTypeConverter implements Converter<String, ItemType> {
    @Override
    public ItemType convert(String code) {

        for (ItemType value : ItemType.values()) {
            if (value.getCode().equals(Integer.valueOf(code))) {
                return value;
            }
        }
        throw new IllegalArgumentException("code非法");
    }
}

(2) 注册上述的StringToItemTypeConverter,在web-admin模块创建com.atguigu.lease.web.admin.custom.config.WebMvcConfiguration,内容如下:

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Autowired
    private StringToItemTypeConverter stringToItemTypeConverter;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(this.stringToItemTypeConverter);
    }
}

 2.4优化

但是我们有很多的枚举类型都需要考虑类型转换这个问题,按照上述思路,我们需要为每个枚举类型都定义一个Converter,并且每个Converter的转换逻辑都完全相同,针对这种情况,我们使用ConverterFactory接口更为合适,这个接口可以将同一个转换逻辑应用到一个接口的所有实现类,因此我们可以定义一个BaseEnum接口,然后另所有的枚举类都实现该接口,然后就可以自定义ConverterFactory,集中编写各枚举类的转换逻辑了。具体实现如下:

(1)在model模块定义com.atguigu.lease.model.enums.BaseEnum接口  

public interface BaseEnum {
    Integer getCode();
    String getName();
}

 (2)令所有com.atguigu.lease.model.enums包下的枚举类都实现BaseEnun接口

web-admin模块自定义com.atguigu.lease.web.admin.custom.converter.StringToBaseEnumConverterFactory

@Component
public class StringToBaseEnumConverterFactory implements ConverterFactory<String, BaseEnum> {
    @Override
    public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) {
        return new Converter<String, T>() {
            @Override
            public T convert(String source) {

                for (T enumConstant : targetType.getEnumConstants()) {
                    if (enumConstant.getCode().equals(Integer.valueOf(source))) {
                        return enumConstant;
                    }
                }
                throw new IllegalArgumentException("非法的枚举值:" + source);
            }
        };
    }
}

(3) 注册上述的ConverterFactory,在web-admin模块创建com.atguigu.lease.web.admin.custom.config.WebMvcConfiguration,内容如下:

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Autowired
    private StringToBaseEnumConverterFactory stringToBaseEnumConverterFactory;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(this.stringToBaseEnumConverterFactory);
    }
}

注意:

最终采用的是ConverterFactory方案,因此StringToItemTypeConverter相关代码可以直接删除。

3.保存或更新标签信息

LabelController中增加如下内容

@Operation(summary = "保存或更新标签信息")
@PostMapping("saveOrUpdate")
public Result saveOrUpdateFacility(@RequestBody LabelInfo labelInfo) {
    service.saveOrUpdate(labelInfo);
    return Result.ok();
}

4. 根据ID删除标签

LabelController中增加如下内容

@Operation(summary = "根据id删除标签信息")
@DeleteMapping("deleteById")
public Result deleteLabelById(@RequestParam Long id) {
    service.removeById(id);
    return Result.ok();
}

4.1@DeleteMapping

有些时候,有的数据可能不再需要了,客户端可以通过HTTP DELETE请求来要移除某个资源。

而 @DeleteMapping 注解就能够非常便捷的声明能够处理DELETE请求的方法。举个栗子:

我们想要有一个能够删除订单资源的API,下面的方法就能实现这一点:

@DeleteMapping("/{orderId}")
@ResponseStatus(code=HttpStatus.NO_CONTENT)
public void deleteOrder(@PathVariable("orderId") Long orderId){
    try{
        repo.deleteById(orderId);
    }catch(EmptyResultDataAccessException e){}
}

在这个方法中,真正负责删除订单的是里面的代码,@DeleteMapping指定deleteOrder()方法处理针对“/orders/{orderId}的DELETE请求。

在该方法中,需要注意的是,@ResponseStatus注解确保的是HTTP状态码为204。对于已经不存在的资源,我们没有必要返回任何的资源数据给客户端,因此DELETE请求中通常没有响应体,我们要以HTTP状态码的形式让客户端知道不要期望得到任何的内容。

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值