zoukankan      html  css  js  c++  java
  • spring的常用注解

    1、@Controller    (注入服务)

    @Component扩展,被@Controller注解的类表示Web层实现,从而见到该注解就想到Web层实现,使用方式和@Component相同;

    在SpringMVC中只需要使用这个标记一个类是Controller,然后使用@RequestMapping和@RequestParam等一些注解用以定义URL请求和Controller方法之间的映射,这样的Controller就能被外界访问到。此外,Controller不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,他们可以通过Controller的方法参数灵活的获取到。

    @Controller
    public class TestController {
     
        @RequestMapping ( "/showView" )
        public ModelAndView showView() {
           ModelAndView modelAndView = new ModelAndView();
           modelAndView.setViewName( "viewName" );
           modelAndView.addObject( " 需要放到 model 中的属性名称 " , " 对应的属性值,它是一个对象 " );
           return modelAndView;
        }
    }

    在上面的例子中,@Controller是标记在类TestController上面的, 所以类TestController就是一个SpringMVC Controller对象。分发处理器会扫描使用了该注解的类的方法,并检测该方法是否调用了@RequestMapping注解。@Controller只是定义了一个控制器类,而使用@RequestMapping注解的方法才是真正处理请求的处理器。然后使用@RequestMapping ( "/showView" )标记在Controller方法上,表示当请求/showView.do 的时候访问的是TestController 的showView 方法,该方法返回了一个包括Model 和View 的ModelAndView 对象。

    单单使用@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要把这个控制器类交给Spring 来管理。

    第一种方式是在SpringMVC 的配置文件中定义MyController 的bean 对象。

    <bean class="com.host.app.web.controller.TestController"/>

    第二种方式是在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。

      < context:component-scan base-package = "com.host.app.web.controller" >
           < context:exclude-filter type = "annotation"
               expression = "org.springframework.stereotype.Service" />
        </ context:component-scan >
    

    注:上面 context:exclude-filter 标注的是不扫描 @Service 标注的类

    2、@RequestMapping 

    使用 @RequestMapping 来映射 Request 请求与处理器,通过这个注解可以定义不同的处理器映射规则,即为控制器指定可以处理哪些URL请求

    用@RequestMapping 来映射URL 到控制器类,或者是到Controller 控制器的处理方法上。当@RequestMapping 标记在Controller 类上的时候,里面使用@RequestMapping 标记的方法的请求地址都是相对于类上的@RequestMapping 而言的;当Controller 类上没有标记@RequestMapping 注解时,方法上的@RequestMapping 都是绝对路径。这种绝对路径和相对路径所组合成的最终路径都是相对于根路径“/ ”而言的。

    在上面那个例子中:

    这个控制器里因为TestController 没有被@RequestMapping 标记,所以当需要访问到里面使用了@RequestMapping 标记的showView 方法时,就是使用的绝对路径/showView.do 请求就可以了。

    如果改成这样:

    @Controller
    @RequestMapping ( "/test" )
    public class TestController {
        @RequestMapping ( "/showView" )
        public ModelAndView showView() {
           ModelAndView modelAndView = new ModelAndView();
           modelAndView.setViewName( "viewName" );
           modelAndView.addObject( " 需要放到 model 中的属性名称 " , " 对应的属性值,它是一个对象 " );
           return modelAndView;
        }
    }

    这种情况下是在控制器上加了@RequestMapping 注解,所以当需要访问到里面使用了@RequestMapping 标记的方法showView() 的时候就需要使用showView 方法上@RequestMapping 相对于控制器TestController上@RequestMapping 的地址,即/test/showView.do 。

    URL路径映射:@RequestMapping("/hello"),可以将多个url映射到同一个方法上。

    窄化请求映射:

    (1)在class上面添加@RequestMapping(url)指定通用请求前缀,限制此类下的所有方法请求url必须以请求前缀开头,通过此方法来分类管理url;

    (2)在方法名上面再设置请求映射url,即添加@RequestMapping注解在方法名上。return “/WEB-INF/jsp/login.jsp”  调用这个方法,重定向的到指定的jsp页面或制定的@RequestMapping的请求路径;

    (3)在浏览器上输入相应地址,完成访问。

    3、@RequestBody

    用于读取http请求的内容(字符串),通过springMVC提供的HttpMessageConverter接口将读取到的内容转换为json、xml等格式的数据,再转换为java对象绑定到Controller类方法的参数上。

    简单点来说,就是把json格式的数据转换为java对象,就举个例子来说明:

    编写一个jsp页面来向后台传递json格式的数据(切记是json格式的):

    <script>
            jsonData();
            function jsonData()
            {
                $.ajax({
                    url:"<%=path%>/user/jsonTest.do",
                    contentType:'application/json;charset=utf-8',//设置json格式
                    data:'{"username":"张三":"address":"福州"}',
                    type:'post',
                    success:function(data){
                        alert(data);
                    },error:function(error){
                        alert(error);
                    }
               })
            }
    </script>

    然后在后台接收一下:

    @RequestMapping("/jsonTest.do")
    public void jsonTest(@RequestBody User user) throws Exception
    {
        System.out.println(user.toString());
    }

    这样的话,前台的两个json数据就会自动匹配到User这个对象的属性中了,当然属性名称要一样的。

    查看一下结果:

    可以看到User这个对象中的username和address都已经自动赋值好了,这个就是json格式的数据转java对象了,可以省去我们在后台将json转成java对象。不过在使用的时候,要注意两边的名称要相同,前台的username要对应java对象中的username这样才能成功。否则得到如下:

    4、@ResponseBody   

    含义:

    @Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。 

    作用:

    用于将Controller中方法返回的对象通过适当的HttpMessageConverter转换为指定格式的数据,如:json、xml等,然后写入到response对象的body区,通过Response响应给客户端。需要注意的是,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。

    使用时机:

    返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

    举个例子:

    @RequestMapping("/login")
      @ResponseBody
      public User login(User user){
        return user;
      }

    User字段是:userName pwd
    那么在前台接收到的数据为:'{"userName":"xxx","pwd":"xxx"}'

    效果等同于如下代码:

    @RequestMapping("/login")
      public void login(User user, HttpServletResponse response){
        response.getWriter.write(JSONObject.fromObject(user).toString());
      }

    @ModelAttribute   

    在方法定义上使用该注解: SpringMVC在调用目标处理方法前, 会先逐个调用在方法级上标注了@ModelAttribute的方法;

    在方法的入参前使用该注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中。

    6、@RequestParam   

    处理简单类型的绑定,用 @RequestParam 绑定 HttpServletRequest 请求参数到控制器方法参数,即在处理方法入参处使用该注解,可以把请求参数传递给请求方法。

     @RequestMapping ( "requestParam" )
       public String testRequestParam( @RequestParam(required=false) String name, @RequestParam ( "age" ) int age) {
           return "requestParam" ;
       } 

    在上面代码中利用@RequestParam 从HttpServletRequest 中绑定了参数name 到控制器方法参数name ,绑定了参数age 到控制器方法参数age 。当没有明确指定从request 中取哪个参数时,Spring 在代码是debug 编译的情况下会默认取跟方法参数同名的参数,如果不是debug 编译的就会报错。此外,当需要从request 中绑定的参数和方法的参数名不相同的时候,也需要在@RequestParam 中明确指出是要绑定哪个参数。在上面的代码中如果访问  /requestParam.do?name=hello&age=1  则Spring 将会把request请求参数name的值hello赋给对应的处理方法参数name ,把参数age 的值1 赋给对应的处理方法参数age 。

    在@RequestParam 中除了指定绑定哪个参数的属性value之外,还有一个属性required,它表示所指定的参数是否必须在request 属性中存在,默认是true,表示必须存在,当不存在时就会报错。在上面代码中我们指定了参数name的required的属性为false ,而没有指定age 的required 属性,这时候如果我们访问/requestParam.do而没有传递参数的时候,系统就会抛出异常,因为age 参数是必须存在的,而我们没有指定。而如果我们访问  /requestParam.do?age=1  的时候就可以正常访问,因为我们传递了必须的参数age ,而参数name是非必须的,不传递也可以。

    value:参数名,即入参的请求参数名字

    如:value="id",表示将请求的参数区的名字为id的参数的值等待传入;

    require:是否必需,默认是true,表示请求中一定要有相应的参数,否则会报400错误。且在每个参数定义前设置。

    defaultValue:默认值,表示如果请求中没有同名参数时的默认值。

    通过 require=true 限定参数id必须传递,如果不传递会报400错误;

    可以使用defaultValue设置默认值,即使 require=true 也可以不传递id参数。

    7、@PathVariable    绑定URL占位符到入参。

    8、@ExceptionHandler    注解到方法上, 出现异常时会执行该方法。

    9、@ControllerAdvice    使一个Controller成为全局的异常处理类, 类中用ExceptinHandler方法注解的方法可以处理所有Controller发生的异常。

    10、@Autowired 

    它可以对类成员变量、方法以及构造函数进行标注,完成自动装配的工作。自动装配的意思就是让Spring从应用上下文中找到对应的bean的引用,并将它们注入到指定的bean。通过@Autowired注解可以完成自动装配。使用@Autowired 来消除代码Java代码里面的getter/setter与bean属性中的property。当然,getter看个人需求,如果私有属性需要对外提供的话,应当予以保留。

    只要对应类型的bean有且只有一个,则会自动装配到该属性上。如果没有找到对应的bean,应用会抛出对应的异常,如果想避免抛出这个异常,则需要设置@Autowired(required=false)。不过,在应用程序设计中,应该谨慎设置这个属性,因为这会使得你必须面对NullPointerException的问题。

    如果存在多个同一类型的bean,则Spring会抛出异常,表示装配有歧义,解决办法有两个: 
    (1)通过@Qualifier注解指定需要的bean的ID; 
    (2)通过@Resource注解指定注入特定ID的bean;

    @Autowired 和 @Service("")的配合使用:

    实例:

    @Controller
    @RequestMapping("/test")
    public class StudentController {
     
        @Autowired
        private StudentService studentService;
     
     
        @RequestMapping("getInfo")
        @ResponseBody
        public int  getInfo(Student student){
            return studentService.insertStu(student);
     
        }
    }

    在Controller中对私有变量用@Autowired标注,因为studentService这个变量是service层接口,所以要找到他的实现类StudentServiceImpl,并在实现类上添加@Service("")的注释。

    @Service("StudentService")
    public class StudentServiceImpl implements StudentService {
        @Autowired
        private StudentDao studentDao;
     
        public int insertStu(Student student){
            return studentDao.insertInfo(student);
        }
    }

    如果不添加@Service("")注释,会报如下错误。因为@Autowired 将寻找与之匹配的bean来创建(类名)bena,但因为删除接口实现类上@Service("")注解,找不到服务对象,@Autowired自然也就找不到实例bean了。

    11、@Override  

    @Override是伪代码,表示重写(当然不写也可以),不过也有好处:

                 (1)可以当注释用,方便阅读;

                 (2)编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。

    例如,你如果没写@Override,而你下面的方法名又写错了,这时你的编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的方法。

    举例:在重写父类的onCreate时,在方法前面加上@Override 系统可以帮你检查方法的正确性。

                       @Override

                        public void onCreate(Bundle savedInstanceState)

                        {…….}

     这种写法是正确的,如果你写成:

                        @Override

                         public void oncreate(Bundle savedInstanceState)

                         {…….}

    编译器会报如下错误:

                         The method oncreate(Bundle) of type HelloWorld must override or implement a supertype method,以确保你正确重写onCreate方法(因为oncreate应该为onCreate)。

    而如果你不加@Override,则编译器将不会检测出错误,而是会认为你为子类定义了一个新方法:oncreate

    12、@Transactional

    使用时机:

    对数据库的数据进行批量或连表操作时,为了保证数据的一致性和正确性,则需要添加事务管理机制进行管理;

    当对数据库的数据操作失败时,事务管理可以很好保证所有的数据 回滚 到原来的数据,如果操作成功,则保证所有的需要更新的数据持久化。

    回滚(Rollback)指的是程序或数据处理错误,将程序或数据恢复到上一次正确状态的行为。

    回滚包括程序回滚和数据回滚等类型。

    删除由一个或多个部分完成的事务执行的更新。为保证应用程序、数据库或系统错误后还原数据库的完整性,需要使用回滚。

    回滚泛指程序更新失败, 返回上一次正确状态的行为。

    回滚与恢复有本质的区别。

    升级回滚:是指因升级中所发生的意外而自动回滚。

    使用优点:

    (1)开发团队达成一致约定,明确标注事务方法的编程风格;

    (2)保证事务方法的执行时间尽可能短,不要穿插其他网络操作,RPC/HTTP请求或者剥离到事务方法外部;

    (3)不是所有的方法都需要事务,如果只有一条修改操作、只读操作不需要事务控制。

    13、@Param

    mybatis提供了一个使用注解来参入多个参数的方法,这种方法需要在接口的参数上添加@Param注解。

    举个例子:

     /**
         * 更新学生信息
         * @param student
         * @return
         */
        int updateInfo(@Param("student") Student student);

    在这个updateInfo的方法中需要传入多个参数,那么在进行mybatis配置的时候,没有办法同事配置多个参数,所以需要@Param这个注解来绑定参数对象。student这个参数中包含了三个对象,用@Param来绑定参数并命名为"student"。并且在mapper.xml文件中调用时,对逐个参数在调用时,要加上 student. 的前缀。如下所示:

     <update id="updateInfo">
            UPDATE test_student SET name=#{student.name},age=#{student.age} WHERE id=#{student.id}
        </update>

    注意事项:在使用@Param来注解时,如果使用#{ } 或者 ${ } 的方式都可以,但如果不是用@Param注解时,则必须使用#{ }方式。

    14、@Component (把普通pojo实例化到spring容器中,相当于配置文件中的 <bean id="" class=""/>)

    定义Spring管理Bean

    在Java配置文件中有两个注解值得注意:

    @Configuration     表示这个.java文件是一个配置文件;

    @ComponentScan   表示开启Component扫描,Spring将会设置该目录以及子目录下所有被@Component注解修饰的类。

    15、@Configuration

     表示这个类是一个spring 配置类,一般这里面会定义Bean,会把这个类中bean加载到spring容器中。

    @Configuration
    @ComponentScan(basePackageClasses = {CDPlayer.class, DVDPlayer.class})
    public class SoundSystemConfig {
    }

    16.@Bean

    在JavaConfig中的属性注入:

    @Bean
    public CDPlayer cdPlayer() {
        return new CDPlayer(sgtPeppers());
    }

    看起来是函数调用,实际上不是:由于sgtPeppers()方法被@Bean注解修饰,所以Spring会拦截这个函数调用,并返回之前已经创建好的bean——确保该SgtPeppers bean为单例。

    17、@ComponentScan

    @ComponentScan主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中。且这个注解默认会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中。

    如果不设置basePackage的话,默认会扫描包的所有类,所以最好还是写上basePackage,减少加载时间。默认扫描**/*.class路径,比如这个注解在com.wuhulala下面,那么会扫描这个包下的所有类还有子包的所有类。比如com.wuhulala.service包的应用。

    总结@ComponentScan的常用方式:

    自定扫描路径下边带有@Controller,@Service,@Repository,@Component注解加入spring容器

    通过includeFilters加入扫描路径下没有以上注解的类加入spring容器

    通过excludeFilters过滤出不用加入spring容器的类

    自定义增加了@Component注解的注解方式

     18、@Service (注入dao)

    用于标注服务层,主要用来进行业务的逻辑处理。@Component扩展,被@Service注解的POJO类表示Service层实现,从而见到该注解就想到Service层实现,使用方式和@Component相同;

    19、@Repository (实现dao访问)

    用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件。@Component扩展,被@Repository注解的POJO类表示DAO层实现,从而见到该注解就想到DAO层实现,使用方式和@Component相同;

    @RequestParam和@RequestBody的区别

    @RequestParam 
    A) 常用来处理简单类型的绑定,通过Request.getParameter() 获取的String可直接转换为简单类型的情况( 由String到 简单类型的转换操作由ConversionService配置的转换器来完成);因为使用request.getParameter()方式获取参数,所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值。
    B)用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式GET、POST。(不设置这个属性,好像这就是默认值)
    C) 该注解有两个属性: value、required; value用来指定要传入值的id名称,required用来指示参数是否必须绑定。

    在方法参数里面如是:

    public WebResponse findReleventPolicyPage(@RequestParam("pageSize") Integer pageSize,
                                               @RequestParam("pageNum") Integer pageNum,
                                               @RequestParam("type") Integer type){}
    

    @RequestBody

    处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据。

    GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。

    POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。

    用于将Controller中方法返回的对象,通过适当的HttpMessageConverter转换为指定格式的数据,如:json、xml等,然后通过Response响应给客户端。

    在方法参数里面如是:

    @RequestMapping("/json_test")
    // 响应json数据,把pojo对象转换成json数据并响应
    @ResponseBody
    public Items jsonTest (@RequestBody Items items){  // 接受json数据并转换成pojo对象
        return items;
    }

    总结

    在GET请求中,不能使用@RequestBody。

    在POST请求,可以使用@RequestBody和@RequestParam,但是如果使用@RequestBody,对于参数转化的配置必须统一。

    举个例子,在SpringMVC配置了HttpMessageConverters处理栈中,指定json转化的格式,如Date转成‘yyyy-MM-dd’,则参数接收对象包含的字段如果是Date类型,就只能让客户端传递年月日的格式,不能传时分秒。因为不同的接口,它的参数可能对时间参数有不同的格式要求,所以这样做会让客户端调用同事对参数的格式有点困惑,所以说扩展性不高。

    如果使用@RequestParam来接受参数,可以在接受参数的model中设置@DateFormat指定所需要接受时间参数的格式。

    另外,使用@RequestBody接受的参数是不会被Servlet转化统一放在request对象的Param参数集中,@RequestParam是可以的。

    综上所述,一般情况下,推荐使用@RequestParam注解来接受Http请求参数。



    原文:https://blog.csdn.net/Steriles_/article/details/81286970
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    k8s记录-helm部署(九)
    k8s记录-master组件部署(八)
    Hadoop记录-Apache hadoop+spark集群部署
    k8s记录-ubuntu安装docker
    Nginx记录-Proxy_pass多个应用配置(转载)
    Java动态调用脚本语言Groovy
    05 吸收应用-会整理还不够?教你吸收、联想、输出、应用
    02 超级搜索术——资源搜索:全面、快速查找全网你想要的任何信息、情报
    01 超级搜索术——信息搜索:全面、快速查找全网你想要的任何信息、情报
    长赢指数基金投资计划-201807(一补仓)
  • 原文地址:https://www.cnblogs.com/qingmuchuanqi48/p/10968956.html
Copyright © 2011-2022 走看看