SpringMVC常用注解以及应用【集成SpringBoot】

前言

Spring是MVC模式的,大大降低了耦合度,提高了开发效率,便于代码管理,
Model,View,Controller 三部分协调工作,MVC思想和观察者模式很相似,但又不同,View是观察者,Model层一旦发生变化,View层即被通知更新。
在这里插入图片描述
MVC要实现的目标是将软件用户界面和业务逻辑分离以使代码可扩展性、可复用性、可维护性、灵活性加强。
这篇博客写的不错
View层是界面,Model层是业务逻辑,Controller层用来调度View层和Model层,将用户界面和业务逻辑合理的组织在一起,起粘合剂的效果。所以Controller中的内容能少则少,这样才能提供最大的灵活性。

而SpringMVC就是MVC模式的一个实现,用户看到的界面叫View层,Service层是对数据库操作的一个封装,比如按id查找就会封装成findById函数,然后再去调用Dao层也就是数据库层的相关操作去操作数据库,Service可以完全不知道Dao层的操作,这就实现了分离,@Controller层则是调节Service层和View之间的关系以及联系的,一个View可以有多个不同的Controller,是策略者模式,具体我也不是很清楚策略者模式,简单来说应该就是View可以有不同的策略来从数据库中拿到数据去渲染吧。

1、常用注解

  1. @RequestMapping用于将url传递给函数,来执行指定Url的指定函数
    value={"/one","/tow"} 可以指定多个url同时访问一个函数
    @RequestMapping(value = {"/index","/jb"}
    method={POST,GET}指定访问方式

2.@RequestParam 用于请求参数,如表单提交上来的参数,还有拼接在URL中的/nb?name=nb&age=16 都可以绑定到函数的参数中
3.@PathVariable 获得URL动态参数 ,默认不指定名字则是以参数名为绑定对象,

@RequestMapping("/body{userid}/")
    @ResponseBody
    public User Body(@PathVariable("userid") Integer id,@ModelAttribute User user) 

4.@RequestHeader获取请求头信息
5.@CookieValue获取Cookie信息,required=false 代表不是必要的 ,defalut="null"可以指定默认值如果没有的话
6.@SessionAttribute 获取session值
7.@SessionAttributes 将Model中的属性加入到sessioon中,一般需要指定,可以根据类型或者在Model中的键来指定多个
value={“user”,},types={User.class}

@SessionAttributes(value = {"nb"})     //value={"user",},types={User.class}
public class C3 {
@ModelAttribute(value = "nb")
    public String before1(ServletRequest request, HttpSession session)
    {

        session.setAttribute("s1","S1");
        //request.setAttribute("username","name-pb");


        return "NB";
    }
}
这样在session中就是储存model中的nb值

8.@ModelAttribute

加了这个注解的,在一个Controller中会先执行,每次有请求来到这个Controller中都会先执行,以便将数据初始化到Model中,其他函数可以在Model中取

主要分三种情况

1、标记着返回具体类的方法中,返回值就是Model中的值

 @ModelAttribute(value = "nb")  "nb"就是Model中的键
    public String before1(ServletRequest request, HttpSession session)
    {

        session.setAttribute("s1","S1");
        //request.setAttribute("username","name-pb");


        return "NB";
    }

2、注释在方法参数中

@RequestMapping(value = "/url")
public String process(@ModelAttribute(value = "name") String name){
    return "success";
}

上述代码中,处理url请求时,会创建String对象,值为url请求中的参数“name”的值,并将该对象添加到Model中,

3、注释在无返回值的函数中,则需要自己创建Model来往Model中添加数据

@ModelAttribute
	public void user(
			@RequestParam("username") String username,
			@RequestParam("pwd") String pwd,Model model) {
		 model.addAttribute("username", username);
		 model.addAttribute("pwd", pwd);
	}

注意:如果原来的Model中已经有了同名的,则会从Model中拿,如果没有,比如下面注释掉的代码,那么如果从Form表单或者URL参数中获取属性参数值,放到对应类型的参数中,注意:此时表单中的组件名和参数属性名称一致,如User对象有两个属性,分别为username,password,则表单中input的名称必须为username,password,才能实现属性值注入。

//    @ModelAttribute("nb")
//    public String Add()
//    {
//        return "NB";
//    }

    @RequestMapping(value = {"/index","/jb"})
    public String Index(@ModelAttribute("nb") String nb,HttpServletRequest request, Model model,Map<String,String> map)
    {
        System.out.println(nb);
        System.out.println("========================="+request.getAttribute("filter01"));
        System.out.println(request.getAttribute("interceptor"));
        model.addAttribute("index","首页");
        request.setAttribute("index","首页");
//        System.out.println(map.get("nb"));
        return "index";
    }

9.@ResponseBody返回JSON类型,SpringBoot会自动解析
10.@ControllerAdvice 全局注解 ,主要用于全局异常处理

@ControllerAdvice
public class AllDataController {

    @ModelAttribute("name")
    public String Name()
    {
        return "panbin";
    }
这时,每个Controller都可以拿到Model中的值
    //异常处理 可以捕获所有Controller中的异常
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String Bad()
    {
        return "Bad";
    }

}

11.@Resource和@Autowired
都是自动注入注解
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:

public class TestServiceImpl {
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao; 
}

@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

12.@Repository
dao层注解



2、SpringMVC异常处理

  1. @ ExceptionHandler
    进行异常处理的方法必须与出错的方法在同一个Controller里面
    不能全局控制异常。每个类都要写一遍。
@Controller      
 2 public class GlobalController {               
 3 
 4    
 8     @ExceptionHandler({MyException.class})        //这里面放的是捕获哪个异常的类 下面就是异常处理函数
 9     public String exception(MyException e) {       
10         System.out.println(e.getMessage());       
11         e.printStackTrace();       
12         return "exception";       
13     }       
14 
15     @RequestMapping("test")       
16     public void test() {       
17         throw new MyException("出错了!");       
18     }                    
19 }     

2.实现 HandlerExceptionResolver 接口
可以捕获全局异常,返回视图

@Component  
 2 public class ExceptionTest implements HandlerExceptionResolver{  
 3 
 4     /**  
 5      * TODO 简单描述该方法的实现功能(可选).  
 6      * @see org.springframework.web.servlet.HandlerExceptionResolver#resolveException(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)  
 7      */   
 8     public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,  
 9             Exception ex) {  
10         System.out.println("This is exception handler method!");  
11         return null;  
12     }  
13 }   

3.使用 @ControllerAdvice+ @ ExceptionHandler 注解

@ControllerAdvice(backPackges="com.xx.xx") //backPackges用于定义扫描哪些包
public class AllDataController {

    @ModelAttribute("name")
    public String Name()
    {
        return "panbin";
    }

    //异常处理
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String Bad()
    {
        return "Bad";
    }



}

这里截了大佬的一段代码*大佬博客
``

/**
 6      * 400 - Bad Request
 7      */
 8     @ResponseStatus(HttpStatus.BAD_REQUEST)
 9     @ExceptionHandler(HttpMessageNotReadableException.class)
10     public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
11         logger.error("参数解析失败", e);
12         return ServiceResponseHandle.failed("could_not_read_json");
13     }
14     
15     /**
16      * 405 - Method Not Allowed
17      */
18     @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
19     @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
20     public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
21         logger.error("不支持当前请求方法", e);
22         return ServiceResponseHandle.failed("request_method_not_supported");
23     }
24 
25     /**
26      * 415 - Unsupported Media Type
27      */
28     @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
29     @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
30     public ServiceResponse handleHttpMediaTypeNotSupportedException(Exception e) {
31         logger.error("不支持当前媒体类型", e);
32         return ServiceResponseHandle.failed("content_type_not_supported");
33     }
34 
35     /**
36      * 500 - Internal Server Error
37      */
38     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
39     @ExceptionHandler(Exception.class)
40     public ServiceResponse handleException(Exception e) {
41         if (e instanceof BusinessException){
42             return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage());
43         }
44         
45         logger.error("服务运行异常", e);
46         e.printStackTrace();
47         return ServiceResponseHandle.failed("server_error");
48     }
49 } 

注意:如果需要自定义错误页,则需要在static目录下定义一个error目录,下面放错误页的html文件,并且按错误代码命名,如404.html,500.html等


3、JSR303数据校验

@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;

1、各种注解,@NULL @NotNULL 标注在JAVA Bean字段上
2、然后在需要验证的地方加@Validator 同时更上Errors 对象

@RequestMapping("/login")
    public String testValid(@Valid User user, BindingResult result){
        if (result.hasErrors()){
            List<ObjectError> errorList = result.getAllErrors();
            for(ObjectError error : errorList){
                System.out.println(error.getDefaultMessage());
            }
        }
           
        return "test";
    }


4、文件上传

构造路径,然后把路径存在数据库里就行

 @RequestMapping("/upload")
    @ResponseBody
    public String Upload(HttpServletRequest request,
    @RequestParam("file")MultipartFile file) 
    throws IOException {
        String path = "D:/1";
        String filename = file.getOriginalFilename();
        File file1 = new File(path+"/"+filename);
        System.out.println("-----------------"+file1.getPath()+"--------------");
        file.transferTo(file1);
        return "SUCCESS";
    }


5、拦截器-------》这篇不错

使用场景

1、日志记录 :记录请求信息的日志
2、权限检查,如登录检查
3、性能检测:检测方法的执行时间



6、启动系统任务 ----->来自这篇

SpringBoot对于系统启动时执行的任务,例如配置文件加载,数据库初始化等操作提供了两种解决方案:CommandLineRunner和ApplicationRunner,两者差别主要在于参数。
​ SpringBoot项目启动时会遍历所有的CommandLineRunner和ApplicationRunner的实现类并调用其中的run方法@Order注解可对于这些实现类调用顺序进行排序
args会被赋值为main的入参

@Component
@Order(2)
public class MyApplicationRunner1 implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<String> nonOptionArgs = args.getNonOptionArgs();  
        System.out.println(nonOptionArgs);
        System.out.println("================");

    }
}
@Component
@Order(1)
public class MyCommandLineRunner implements CommandLineRunner {
    @Override //可变参数String...args
    public void run(String... args) throws Exception {
        System.out.println(Arrays.toString(args));
        System.out.println("------------------");
    }
}

7、SpringBoot定时器

假设我们已经搭建好了一个基于Spring Boot项目,首先我们要在Application中设置启用定时任务功能@EnableScheduling。
其中 @EnableScheduling 注解的作用是发现注解@Scheduled的任务并后台执行。

@Component
public class MyScheduler {

    @Scheduled(fixedRate = 2000) //每隔两秒启动
    public void Test1()
    {
        System.out.println("任务启动");
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值