SpringMVC学习(四)------------------注解详解

一.注解详情

注解的内容实在是又多又麻烦哦,这里基本上都是按学的注解来的,大概上就是罗列很多,一方面是能够促进记忆,另一方面也方便自己查阅相关的注解。也有穿插一部分路径知识,有一部分没搞懂,老师讲的也不清楚,也可能我憨,烦躁哦。        ----------看注解看的憨了

一.@RequestMapping

  • value 写的是路径,是一个数组的形式,可以匹配多个路径。
  • path 实测是和value作用一致的,二者任选其一都可以,作用一样,下面附的图是@RequsetMapping注解的源码部分,个人觉得很奇怪,Mapping作为映射,我能理解他映射的肯定是个路径,也就是path,但是path别名是value,value别名又是path,一开始看的我是有点懵了。什么骚操作,后来查了@AliasFor别名的标签,大概意思就是他们两个互为别名,可以理解为他们实际的就是同一个东西。
//    @RequestMapping(value={"/m1","/m2"})
    @RequestMapping(path = {"/m1","/m2"})
    public String m(){
        System.out.println("进来了");
        return "forward";
    }

两种代码注解方式都可以,源码如下:

在这里插入图片描述

  • method 来说,格式是:@RequestMapping(method=“RequestMethod.GET”)这里的method的作用是缩小了映射的范围,也就是在这里是get的情况下,该控制器只能接受get类型的请求,其他类型的请求会被拒绝。
  • params 格式是:@RequestMapping(params={“girl”,“boy”}),这里的params实质作用也是缩小了映射的范围,必须提供这两个参数以后,才能访问。也可以限制参数值,params={“girl=wang”,"boy=“yu”}这种写法就直接限定了参数的值。
  • headers 能够影响浏览器行为————一般很少用到
  • consumers 消费者,媒体类型,可以限定必须为application/json;charset=UTF-8
  • produces 产生的响应的类型

二.补充一下请求路径的知识

springMVC支持ant(蚂蚁)风格

  • ? 一个任意字符,斜杆除外
  • * 0到n个任意 字符随便都行,不能是斜杠
  • ** 支持任意层路径,写法:/m/ * * 这样才可以体现出来,如果是/m * *那效果就等同于m后面任意多个字符

三.@GetMapping、@PostMapping······

  • 相当于把RequsetMapping中的method方法值改成了GET,Post,限定了只支持的请求类型,其实有很多请求。

四.对于非get post请求的支持

  • 对于非get post请求的支持,需要添加额外的内容,要增加一个过滤器来额外处理
  • 返回的不再是页面而是数据
  <!--注册一个支持所有http请求类型的过滤器-->
  <filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  • 表单里面还要添加一个隐藏的参数
    name="_method" value=“DELETE”
  • 不知道什么原因嗷,这个没搞定-------发现原因了,发post请求才可以,而且路径缺少了一个y,这个路径的 东西,后面不然再发一个,单独写出来,有看到一个小技巧。

五.关于静态资源访问的问题

  • 由于我们的servlet设置了URL匹配的方式为/所以,它将静态资源也当作了一个后台的请求,比如http://localhost:8080/y/static/css/index.jsp
    它尝试去匹配一个static/css/index.jsp的Controller里面的ReuqestMapping的组合,因为没有,所以404,解决方式很多,最简单的,是让springmvc单独处理,将这些交给容器的默认的Servlet处理,就不让DispatcherServlet来处理了。
    eg:使用index页面,链接了一个css文件,index.css,访问index页面,打开控制台后的输出有
    在这里插入图片描述
    可以看到,index.css的type是stylesheet文件,静态资源访问不到,报了404。
  • 解决方法:在springMVC的xml中加入下面的内容
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation= http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd

还有这个在这里插入图片描述
即可,重新访问的结果如下:
在这里插入图片描述

注意:如果只加了default-servlet-handler的话,Controller资源全部就都不能访问了,必须加上annotation-driven,也就是开启注解,才可以。

六.@PathVariable()

  • 其实是一种url的风格吧,叫做restful
  • 具体内容参考罗伊菲尔丁的博士论文
  • 在这里插入图片描述
  • 访问路径的写法:http://localhost:8080/y/product/add/name/222/228.3f

七.@Responsebody

  • 返回数据的,一般情况下返回json格式

八.关于POST请求中文乱码问题解决

  • 之前在javaMVC中处理----------写一个过滤器
  • 现在springMVC提供了一个编码过滤器,直接在web.xml中进行注册就可以了,init-param中的内容可以点进去CharacterEncodingFilter中就能对应上
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!--指定字符编码-->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <!--这个是是否强制请求编码-->
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

九.@ModelAttribute-----controller里面任意一个处理具体的方法之前都会执行

  • 使用方式(一):
@Controller
@RequestMapping("/user")
public class User2Controller {

    //就是在controller里面任意一个处理具体的方法之前都会执行,类似过滤器
    @ModelAttribute
    public User init(){
        User user = new User();
        user.setName("冬雨");
        return user;
    }
    @RequestMapping("/login")
    public String login(Model model){
        System.out.println(model.containsAttribute("user"));
        System.out.println(model.containsAttribute("u"));
        System.out.println(model.containsAttribute("gogogo"));
        return "msg";
    }
}
  • 如果某些对象从头到尾每次请求中都要存在,不消失,就适合这么用
  • 使用方式(二):不用return的方式
 @ModelAttribute
    public void init(Model model){
        User user = new User();
        user.setName("周");
        model.addAttribute("user",user);
    }
@RequestMapping("/login")
public String login(@ModelAttribute User user){
        System.out.println(user.getName());
        return "msg";
}
  • 这里要是没有传user.name那么user.name的值不会变,依然是周,但是如果一个表单提交数据中有一个input的name是name,那么这里再输出user.getName就会变成表单数据中的内容,相当于覆盖掉了原始的数据。

十.@RequestBody

  • json数据,不是通过form表单传递
    ajax({
    data:
    })

十一.@SessionAttributes------负责存会话

  • 这个用在类上,会将模型自动填充到会话中
  • SessionAttributes和SessionAttribute两个的用法乱七八糟的,如果用model就很简单,一旦用下面这个写法就真的就看不懂,这特么SessionAttribute中的内容到底是数值的类型还是name,页面输出的时候到底是输出SessionAttributes中的还是我接受的,然后SessionAttribute检查会话到底是监测名字还是监测tmd
@Controller
@RequestMapping("/dog")
@SessionAttributes("dog")
public class dogController {

    @RequestMapping("/regist")
    public String init(Dog dog){
        return "dog";
    }
    //检查当前会话里面是否有dog
    @RequestMapping("/login")
    public String login(@SessionAttribute Dog dog){
        return "redirect:/jsp/dog.jsp";
    }
}
  • 格式是:@SessionAttributes(),括号中的内容是addAttribute的键名,如果要存多个attribute(属性),写法如下
    在这里插入图片描述
@Controller
@RequestMapping("/user3")
@SessionAttributes("user")
public class User3Controller {

    @ModelAttribute("user")
    public void init(Model model){
        User user = new User();
        user.setName("hanhan");
        model.addAttribute("user",user);
    }
    //转发后一般数据就丢失了,这里查看是否是会话,会话不会丢失
    @RequestMapping("/login")
    public String login(@ModelAttribute User user){
        System.out.println(user.getName());
        return "redirect:/jsp/user3.jsp";
    }
}

十二.@SessionAttribute---------负责检查会话中有没有某个对象

  • 要求当前这次访问当中的会话里面必须有某个对象

十三.@RestController

  • 作用:如果你的整个controller中的方法都是@ResponseBody的情况下,你就可以用@RestController去替换你的@Controller,并且不再需要@ResponseBody这个注解。
  • @RestController = @Controller + @ResponseBody

二.关于form表单提交数据的方式

方式一:通过属性名字绑定
  • 通过属性名称进行绑定,可以完成数据传递。
  • 页面中表单元素的name值要和后台的形参的名字保持一致
  • 如果有多个,多个形参按名字绑定即可,当传入的值较多的时候就有点麻烦
<html>
<head>
    <title>Title</title>
</head>
<body>

<form action="${ctx}/user/put" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="text" name="name">
    <input type="submit" value="提交">
</form>
</body>
</html>

@Controller
@RequestMapping("/user")
public class UserController {

    @PutMapping("/put")
    //需要额外json包的支持,如果return map的话
    @ResponseBody
    public String put(String name){
        System.out.println(name);
//        Map<String,String> map = new HashMap<>();
//        map.put("msg","ok");
        return "ojbk";
    }
}

方式二:@RequestParam传递请求参数
  • jsp页面不变
  • 后台参数略有变化
   @PutMapping("/put")
    //需要额外json包的支持
    @ResponseBody
    public String put(@RequestParam("name") String name,@RequestParam("password") String password){
        System.out.println(name+password);
//        Map<String,String> map = new HashMap<>();
//        map.put("msg","ok");
        return "ojbk";
    }
方式三:直接使用pojo形式传递
  • jsp不变
  • 后台
    @PutMapping("/put")
    //需要额外json包的支持
    @ResponseBody
    public String put(User user){
        System.out.println(user.getName()+user.getPassword());
//        Map<String,String> map = new HashMap<>();
//        map.put("msg","ok");
        return "ojbk";
    }

二.关于form表单提交日期格式数据问题

  • 问题:在前端表单给后端传了Date类型的数据以后,假如使用pojo接收传递的值,那就会报错,不能获取到Date的具体值。
  • 一.处理日期(没有时间)
    @InitBinder("user")
    public void init(WebDataBinder dataBinder){
        //这里指定什么格式,前端就只能传什么格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //这里是对日期格式是否严格匹配
        sdf.setLenient(false);
        //
        dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,false));
    }
    @PostMapping("/put")
    @ResponseBody
    public String put (@ModelAttribute("user") User user){
        System.out.println(user.getDate());
        return user.getDate().toString();
    }
  • 二.上述方式不指定名字,根据数据类型一样可以分析解析转换成功
    @InitBinder
    public void init(WebDataBinder dataBinder){
        //这里指定什么格式,前端就只能传什么格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //这里是对日期格式是否严格匹配
        sdf.setLenient(false);
        //
        dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,false));
    }
    @PostMapping("/put")
    @ResponseBody
    public String put (@ModelAttribute User user){
        System.out.println(user.getDate());
        return user.getDate().toString();
    }
  • 三.在pojo属性上面添加额外的注解
 @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date date;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值