Spring自定义注解实现Controller获取想要的数据

最近看组内一个哥们写了一个HandlerAdapter,能自动获取Http请求里面的Cookie并组装成一个Model来直接使用。觉得很牛逼。因此自己做了一个,特来分享。

原理:

利用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter。

在DispatcherServlet里面定义了:

private List<HandlerAdapter> handlerAdapters;

用于Servlet初始化的时候查找配置了的HandlerAdapter。再在Servlet请求到来之时通过调用doService层层调用

	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (logger.isTraceEnabled()) {
				logger.trace("Testing handler adapter [" + ha + "]");
			}
			if (ha.supports(handler)) {
				return ha;
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: Does your handler implement a supported interface like Controller?");
	}

让它们去处理Handler。此处贴上一种实现代码:

Demo.java:

package com.hp.share.annocation;

public class Demo {

    private int id;
    private String name;
    private byte sex;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public byte getSex() {
        return sex;
    }
    public void setSex(byte sex) {
        this.sex = sex;
    }
    public Demo() {
        this.id = 1001;
        this.name = "hello world";
        this.sex = 1;
    }

    @Override
    public String toString() {
        return "Demo [id=" + id + ", name=" + name + ", sex=" + sex + "]";
    }
}

DemoAnnotation.java:

package com.hp.share.annocation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.PARAMETER })
public @interface DemoAnnotation {
}

DemoProcessor.java:

package com.hp.share.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.hp.share.annocation.Demo;
import com.hp.share.annocation.DemoAnnotation;

public class DemoProcessor implements HandlerMethodArgumentResolver {

    private static Logger logger = LoggerFactory.getLogger(DemoProcessor.class);

    public boolean supportsParameter(MethodParameter parameter) {
        boolean res = parameter.getParameterAnnotation(DemoAnnotation.class) != null;
        logger.info("开始校验 : {}", res);
        return res;
    }

    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        logger.info("这是注解执行的标志~~~");
        return new Demo();
    }
}

DemoController.java:

package com.hp.share.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.common.base.Preconditions;
import com.hp.share.annocation.Demo;
import com.hp.share.annocation.DemoAnnotation;

@Controller
public class DemoController {

    @RequestMapping("/hello")
    @ResponseBody
    public String demo(@DemoAnnotation Demo req) {

        Preconditions.checkNotNull(req);
        System.out.println(String.valueOf(req));

        return "success";
    }
}

需要配置:

	<bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<property name="customArgumentResolvers">
			<list>
				<bean class="com.hp.share.handler.DemoProcessor" />
			</list>
		</property>
	</bean>
	<mvc:annotation-driven />

此处切记<mvc:annotation-driven />并且它得在所有bean的下面。如果你配置了AnnotationMethodHandlerAdapter,就更应该将其放在配置的最后面了。

具体原因可查看Spring源码(跟DispatcherServlet即可)

如果测试时发现自己的代码不好使,可debug  DispatcherServlet。多半是因为【配置出错或者是HandlerAdapter引用错误(还是配置错误)

就这样,就可以轻轻松松的获取到自己自定义注解的内容了。如果想对Method进行注解,依然可以使用这个类的,详情可查看源码。

时间: 2024-08-22 20:19:32

Spring自定义注解实现Controller获取想要的数据的相关文章

【转】spring 自定义注解(annotation)与 aop获取注解

首先我们先介绍Java自定义注解. 在开发过程中,我们实现接口的时候,会出现@Override,有时还会提示写@SuppressWarnings.其实这个就是Java特有的特性,注解. 注解就是某种注解类型的一种实例,我们可以把它用在某个类上进行标注.下面这张图解释注解都是什么? 上图可以看出注解大体分为三种:元注解,标记注解,一般注解: 这一块其他的我就不多做介绍,我们这里主要说一下如何定义自己的注解,在这之前我们必须了解标准元注解和相关定义注解的语法.元注解的作用就是负责注解其他注解.Jav

spring - 自定义注解

本自定义注解的作用:用于控制类方法的调用,只有拥有某个角色时才能调用. java内置注解 1.@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: ElemenetType.CONSTRUCTOR   构造器声明 ElemenetType.FIELD   域声明(包括 enum 实例) ElemenetType.LOCAL_VARIABLE   局部变量声明 ElemenetType.METHOD   方法声明 ElemenetType.PACKAGE   包声明

深入Spring 自定义注解加载和使用

前言 在工作中经常使用Spring的相关框架,免不了去看一下Spring的实现方法,了解一下Spring内部的处理逻辑.特别是开发Web应用时,我们会频繁的定义@Controller,@Service等JavaBean组件,通过注解,Spring自动扫描加载了这些组件,并提供相关的服务.Spring是如何读取注解信息,并注入到bean容器中的,本文就是通过嵌入Spring的Bean加载,来描述Spring的实现方法.完整的例子都在Github上了. 自定义注解 先看一个最简单的例子,在使用Spr

SpringMVC拦截器+Spring自定义注解实现权限验证

设计思路 主要针对需要登录后操作的接口进行校验.接入层在对外暴露接口后,网页.APP.第三方等等途径进行访问接口.用户请求首先会被SpringMVC拦截器拦截到,在拦截器里第一步就是需要校验用户的登录身份(由于是分布式系统这里采用的是userId+accessToken方式来校验),登录校验通过之后再进行用户权限校验,此时会自动拦截@AuthValidate注解的method(核心),如果权限校验失败则抛出权限不足异常,否则校验通过之后再执行具体接口并返回结果. 1.自定义注解 1 packag

创建spring自定义注解进行自动装配

1.创建自定义注解 1 import org.springframework.beans.factory.annotation.Qualifier; 2 import java.lang.annotation.ElementType; 3 import java.lang.annotation.Retention; 4 import java.lang.annotation.RetentionPolicy; 5 import java.lang.annotation.Target; 6 7 8

Spring自定义注解扫描的实现

目标:实现自定义spring自动扫描注解.主要为后期实现分布式服务框架自动注解提供技术支持 技术分析:通过配置组件扫描标签使spring解析标签. 1. JewelScanBeanDefaultParser.java public class JewelScanBeanDefaultParser implements BeanDefinitionParser { private static final String RESOURCE_PATTERN = "/**/*.class";

使用Spring自定义注解生产Http接口描述信息

最近在做一个手机后台项目,使用的是SpringMVC,开发的接口是HTTP接口.在接口写完后需要在网页中吧接口的名称测试地址等信息添加到网页中,感觉这样很麻烦还容易漏.于是就写了一个自定义注解通过注解的方式将接口的描述信息加入到接口中,通过注解描述接口信息并且生产接口测试地址 先看使用方法及最终效果 @ResponseBody @RequestMapping("/getBusWaiting") @AppInterface(value="获取候车信息",group=&

spring --自定义注解(配合@Aspect)

1:首先,声明自定义注解 @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface DtTransactional { /* * Whether need to rollback */ public boolean includeLocalTransaction() default true; public boolean confirmMethodExist() default tru

java遍历复杂json字符串获取想要的数据

https://blog.csdn.net/qq_34309663/article/details/80508125 java如何解析复杂的json数据关于json处理的包有好几个,比如jackson.Gson.Fastjson.Gson是谷歌做的,功能强大:Fastjson是阿里巴巴做的,性能更快.具体用哪个,开心就好.我这里两个都没用,用的是java的一个类库-json-lib.如果你用的是maven构建的项目,添加依赖请注意加上JDK版本15,详情请戳这里ok,多的不说了,让我们直接来解析