当前位置: 首页 > article >正文

Spring学习笔记_42——@CookieValue

@CookieValue

1. 介绍

@CookieValue 注解是 Spring Framework 中的一个注解,用于从 HTTP 请求中的 Cookie 中提取值并将其绑定到控制器方法的参数上。

这个注解在开发基于 Spring MVC 的 Web 应用时非常有用,因为它允许开发者方便地访问和操作客户端发送到服务器的 Cookie 数据。

2. 场景

@CookieValue 注解通常用于以下场景:

  1. 身份验证和会话管理:从 Cookie 中获取用户的身份验证令牌或会话 ID。
  2. 用户偏好设置:读取用户设置的主题、语言等偏好信息。
  3. 跟踪和分析:读取用于用户跟踪、分析等的 Cookie 数据。

3. 源码

/**
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.0
 * @see RequestMapping
 * @see RequestParam
 * @see RequestHeader
 * @see org.springframework.web.bind.annotation.RequestMapping
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CookieValue {
  
  // String类型的属性,用于指定Cookie的名称
	@AliasFor("name")
	String value() default "";

  // Spring4.2版本开始提供的String类型的属性
  // 作用与value属性相同
	@AliasFor("value")
	String name() default "";
  
  // boolean类型的属性,用于指定是否必须有Cookie信息
  // true必须有
  // false 非必须有
  // 如果设置为true, 请求时没有此Cookie信息会强制报错
  // 默认为true
	boolean required() default true;
  
  // String类型的属性,用于指定Cookie的默认值
	String defaultValue() default ValueConstants.DEFAULT_NONE;
}

4. Demo

4.1 用于身份验证
  1. 用户登录成功后,将验证信息添加到Cookie中进行返回
@PostMapping("/login")
public ResponseEntity<String> login(@RequestParam String username, @RequestParam String password) {
    // 假设这里已经完成了用户名和密码的验证
    String authToken = generateAuthToken(username); // 生成认证令牌

    // 创建Cookie
    Cookie cookie = new Cookie("authToken", authToken);
    cookie.setHttpOnly(true); // 设置为 HttpOnly 防止 XSS 攻击
    cookie.setSecure(true); // 如果使用 HTTPS,设置为 true
    cookie.setPath("/"); // 设置路径为根路径

    // 将Cookie添加到响应中
    HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    response.addCookie(cookie);

    return ResponseEntity.ok("Login successful");
}
  1. 使用@CookieValue注解,提取请求中的Cookie信息进行验证
@RestController
@RequestMapping("/secure")
public class SecureController {

    @GetMapping("/data")
    public ResponseEntity<String> getSecureData(@CookieValue(value = "authToken", required = true) String authToken) {
        // 这里可以调用服务层的方法来验证 authToken
        if (isValidToken(authToken)) {
            // 返回受保护的数据
            return ResponseEntity.ok("Secure data for authenticated user");
        } else {
            // 认证失败,返回未授权状态
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
        }
    }

    private boolean isValidToken(String token) {
        // 实现你的令牌验证逻辑
        // 例如,检查令牌是否存在于数据库中,是否过期等
        return token.equals("valid-token"); // 示例中的简单验证
    }
}
4.2 用于多语言检测
  1. 定义一个支持语言的枚举
public enum Language {
    ENGLISH("en"),
    FRENCH("fr"),
    GERMAN("de"),
    // 添加更多语言...
    UNKNOWN("unknown");

    private final String code;

    Language(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public static Language fromCode(String code) {
        for (Language language : values()) {
            if (language.getCode().equals(code)) {
                return language;
            }
        }
        return UNKNOWN;
    }
}
  1. 创建Controller处理多语言请求
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LanguageController {

    // 默认语言,可以从配置文件中读取
    private static final String DEFAULT_LANGUAGE_CODE = "en";
    private static final Language DEFAULT_LANGUAGE = Language.ENGLISH;

    @GetMapping("/")
    public String showHomePage(
            @CookieValue(name = "lang", defaultValue = DEFAULT_LANGUAGE_CODE) String langCode,
            Model model) {

        // 将Cookie中的语言代码转换为Language枚举
        Language language = Language.fromCode(langCode);

        // 如果Cookie中的语言代码无效,则使用默认语言
        if (language == Language.UNKNOWN) {
            language = DEFAULT_LANGUAGE;
        }

        // 将选中的语言添加到模型中,以便在视图(如JSP、Thymeleaf等)中使用
        model.addAttribute("language", language);

        // 返回视图名称,例如"home"
        return "home";
    }

    // 其他与语言相关的映射和方法...
}

http://www.kler.cn/a/403412.html

相关文章:

  • java实现小程序接口返回Base64图片
  • Oracle数据库安全扫描1158/3938端口出现弱SSL加密算法解决方法之一
  • Android 设置 bottomnavigation 底部导航栏的样式
  • 掌握 Spring 事务管理:深入理解 @Transactional 注解
  • Git 提交的相对引用
  • SpringCloud Gateway转发请求到同一个服务的不同端口
  • Android CTA配置和3C认证、SRRC认证
  • IT资产管理工具-NetBox
  • Python爬虫 | Scrapy 爬虫框架学习
  • CAAS 和 IAAS
  • 工业机器视觉中图像质量评估
  • Spring Boot 注解
  • 问题: redis-高并发场景下如何保证缓存数据与数据库的最终一致性
  • 安卓开发实现图像处理相关功能
  • 三十九、Python(pytest框架-中)
  • Spark核心组件解析:Executor、RDD与缓存优化
  • k8s1.31版本最新版本集群使用容器镜像仓库Harbor
  • Go Web服务中如何优雅平滑重启?
  • 基于Quartus Prime18.1的安装与FPGA的基础仿真(联合Modelsim)教程
  • js实现购物车功能
  • Qt问题:不同文件中相同命名空间的多个 Q_NAMESPACE
  • ThinkPHP框架和Laravel框架区别
  • pytorch训练的双卡,一个显卡占有20GB,另一个卡占有8GB,怎么均衡?
  • Elasticsearch面试内容整理-核心概念与数据模型
  • K8S基础概念和环境搭建
  • Flink基础面试题