【SpringMVC】关于SpringMVC注解开发的一些杂记

【SpringMVC】关于SpringMVC注解开发的一些杂记

一、@RequestMapping注解类型

1、注解的使用

Spring 通过 @Controller 注解找到相应的控制器类后,还需要知道控制器内部对每一个请求是如何处理的,这就需要使用 org.springframework.web.bind.annotation.RequestMapping 注解类型。RequestMapping 用于映射一个请求或一个方法,其注解形式为 @RequestMapping,可以使用该注解标注在一个方法或一个类上。

(1)标注在方法上
  • 当标注在方法上时,该方法将成为一个请求处理方法,它会在程序接收到对应的URL请求时被调用。

    例:

    @RequestMapping(value = "/demo")
    public String demo() {
        System.out.println("hzz1服务器被访问……………………………………");
        return "main";
    }
    
  • 上述代码中的demo方法就可以通过地址 http://localhost:8080/demo 进行访问。

(2)标注在类上
  • 当标注在一个类上时,该类中的所有方法都将映射为相对于类级别的请求,请求控制器所处理的所有请求都被映射到value属性值所指定的路径下。

    例:

    @Controller
    @RequestMapping(value = "/hzz1")
    public class DemoAction {
    
        @RequestMapping("/demo")
        public String demo() {
            System.out.println("hzz1服务器被访问……………………………………");
            return "main";
        }
    
    }
    
  • 由于在类上添加了 @RequestMapping 注解,并且其vlaue属性值为“/hzz1”, 因此上述代码方法的请求路径将变为 http://localhost:8080/hzz1/demo 。如果该类中还包含其他方法,那么在其他方法的请求路径中也需要加入"/hzz1"。

2、@RequestMapping注解的属性
属性名类型描述
nameString可选,用于为映射地址指定的别名
vlaueString[]可选,默认,用于映射一个请求和一种方法,可以标注在方法或类上
methodRequestMethod[]可选,指定该方法处理那种类型的请求,如GET、POST等
paramsString[]可选,用于指定Request中必须包含某些参数的值,才可以通过其标注的方法处理
headersString[]可选,用于指定Request中必须包含某些header的值,才可以通过其标注的方法处理
consumesString[]可选,用于指定处理请求的提交内容类型(Context-Type),如 application/json、text/html等
producesString[]可选,用于指定返回的内容类型,返回的内容类型必须是request请求头(Accept)中所包含的类型

二、五种数据提交的方式

注:前四种数据注入方式,会自动进行类型转换。但无法自动转换日期类型。

  • 视图页面

    <%--
      Created by IntelliJ IDEA.
      User: 34162
      Date: 2022/5/1
      Time: 22:09
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <form action="${pageContext.request.contextPath}/type.action" method="post">
            <input type="submit" value="提交数据">
        </form>
    
        <br><br>
        <h2>1、单个数据注入</h2>
        <form action="${pageContext.request.contextPath}/one.action">
            <p>
                <label>姓名:</label>
                <input type="text" name="name">
            </p>
            <p>
                <label>年龄:</label>
                <input type="text" name="age">
            </p>
            <input type="submit" value="提交">
        </form>
    
        <br><br>
        <h2>2、对象封装注入</h2>
        <form action="${pageContext.request.contextPath}/two.action">
            <p>
                <label>姓名:</label>
                <input type="text" name="name">
            </p>
            <p>
                <label>年龄:</label>
                <input type="text" name="age">
            </p>
            <input type="submit" value="提交">
        </form>
    
        <br><br>
        <h2>3、动态占位符提交</h2>
        <a href="${pageContext.request.contextPath}/three/张三/123.action">占位符提交(仅用于超链接)</a>
    
        <br><br>
        <h2>4、请求参数名称与形参不一致</h2>
        <form action="${pageContext.request.contextPath}/four.action" method="post">
            <p>
                <label>姓名:</label>
                <input type="text" name="uName">
            </p>
            <p>
                <label>年龄:</label>
                <input type="text" name="uAge">
            </p>
            <input type="submit" value="提交">
        </form>
    
        <br><br>
        <h2>5、使用HttpServletRequest对象提取</h2>
        <form action="${pageContext.request.contextPath}/five.action">
            <p>
                <label>姓名:</label>
                <input type="text" name="uName">
            </p>
            <p>
                <label>年龄:</label>
                <input type="text" name="uAge">
            </p>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    
  • action代码

    package com.Etui.controller;
    
    import com.Etui.entity.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import javax.servlet.http.HttpServletRequest;
    
    @Controller
    public class DataSubmit {
    
        @RequestMapping(value = "/type", method = RequestMethod.GET)
        public String dataSub1() {
            System.out.println("通过GET方法访问……………………");
            return "main";
        }
    
        @RequestMapping(value = "/type", method = RequestMethod.POST)
        public String dataSub2() {
            System.out.println("通过POST方法访问……………………");
            return "main";
        }
    
        @RequestMapping("/one")
        public String one(String name, Integer age) {
            System.out.println("username = " + name + ", age = " + (age + 10));
            return "main";
        }
    
        @RequestMapping("/two")
        public String two(User user) {
            System.out.println(user);
            return "main";
        }
    
        // 若形参名称与地址中参数名相同,此处也可以不使用PathVariable注解
        @RequestMapping("/three/{uName}/{uAge}")
        public String three(
                @PathVariable(value = "uName") String name,
                @PathVariable(value = "uAge") String age
        ) {
            System.out.println("username = " + name + ", age = " +age);
            return "main";
        }
    
        /**        前端页面中提交的参数
         *         <p>
         *             <label>姓名:</label>
         *             <input type="text" name="uName">
         *         </p>
         *         <p>
         *             <label>年龄:</label>
         *             <input type="text" name="uAge">
         *         </p>
         */
        @RequestMapping("/four")
        public String four(
                @RequestParam(value = "uName") String name,
                @RequestParam(value = "uAge") Integer age
        ) {
            System.out.println("username = " + name + ", age = " + age);
            return "main";
        }
    
        @RequestMapping("/five")
        public String five(HttpServletRequest request) {
            String name = request.getParameter("uName");
            Integer age = Integer.parseInt(request.getParameter("uAge"));
            System.out.println("username = " + name + ", age = " + age);
            return "main";
        }
    
    }
    

三、在POST形式表单提交中请求参数中文乱码问题

  • 解决方案

    在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的。

  • 在web.xml中添加如下过滤器即可

    <!-- 创建过滤器,用于修改POST请求的默认编码格式 -->
    <filter>
        <filter-name>encodingType</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--
            private String encoding;
            private boolean forceRequestEncoding;
            private boolean forceResponseEncoding;
        -->
        <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>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingType</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

四、SpringMVC的四种跳转方式

默认的跳转是请求转发,直接跳转到jsp页面展示,还可以使用框架提供的关键字redirect:,进行一个重定向操作,包括重定向页面和重定向action,使用框架提供的关键字forward:,进行服务器内部转发操作,包括转发页面和转发action。当使用redirect:和forward:关键字时,视图解析器中前缀后缀的拼接就无效了。

  • 前端测试代码

    <%--
      Created by IntelliJ IDEA.
      User: 34162
      Date: 2022/5/2
      Time: 21:18
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <br><br>
    <a href="${pageContext.request.contextPath}/one.action">1、请求转发至页面(默认)</a>
    <br><br>
    <a href="${pageContext.request.contextPath}/two.action">2、请求转发至action</a>
    <br><br>
    <a href="${pageContext.request.contextPath}/three.action">3、重定向至页面</a>
    <br><br>
    <a href="${pageContext.request.contextPath}/four.action">4、重定向至action</a>
    </body>
    </html>
    
  • 功能实现代码(action)

    package com.Etui.controller;
    
    import com.Etui.entity.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Map;
    
    @Controller
    public class JumpAction {
    
        @RequestMapping("/one")
        public String one() {
            System.out.println("请求转发至页面……………………………………");
            return "main";
        }
    
        @RequestMapping("/two")
        public String two() {
            System.out.println("请求转发至action……………………………………");
            return "forward:/other.action";
        }
    
        @RequestMapping("/three")
        public String three() {
            System.out.println("重定向至页面……………………………………");
            return "redirect:/admin/main.jsp";
        }
    
        @RequestMapping("/four")
        public String four() {
            System.out.println("重定向至action……………………………………");
            return "redirect:/other.action";
        }
        
        @RequestMapping("/other")
        public String other() {
            System.out.println("other…………………………");
            return "main";
        }
    
    }
    

五、SpringMVC 支持的默认参数类型与返回类型

1、参数类型
  • HttpServletRequest

  • ServletResponse、HttpServletResponse

  • HttpSession

  • WebRequest、NativeWebRequest

  • java.uitl.Locale

  • java.uitl.TimeZone、java.time.ZoneId

  • java.io.InputStream、java.io.Reader、java.io.OutputSteam、java.io.Writer

  • org.springframework.http.HttpMethod

  • java.security.Principal

  • @PathVariable、@MatrixVariable、@RequestParam、@RequestHeader、@RequestBody、@RequestPart、@SessionAttribute、@RequestAttribute

  • java.uitl.Map、org.springframework.ui.Model、org.springframework.ui.ModelMap

  • RedirectAttributes

  • Errors、BindingResult

  • SessionStatus

  • UriComponentBuilder

  • 常用的几个,示例:

    @RequestMapping("/five")
    public String five( // 通常用作数据共享
            HttpServletRequest request,
            HttpServletResponse response,
            Model model,
            ModelMap modelMap,
            Map map
    ) {
        User user = new User("甘雨", 19);
        request.setAttribute("servletRequest", user);
        model.addAttribute("model", user);
        modelMap.addAttribute("modelMap", user);
        map.put("map", user);
        return "main";
    }
    
    
    /**
        <form action="${pageContext.request.contextPath}/four.action" method="post">
            <p>
                <label>姓名:</label>
                <input type="text" name="uName">
            </p>
            <p>
                <label>年龄:</label>
                <input type="text" name="uAge">
            </p>
            <input type="submit" value="提交">
        </form>
    */
    @RequestMapping("/four")
    public String four(
      	@RequestParam(value = "uName") String name, 
       	@RequestParam(value = "uAge") Integer age
    ) {
        System.out.println("username = " + name + ", age = " + age);
        return "main";
    }
    
2、返回值类型
  • ModelAndView
  • Model
  • Map
  • View
  • String
  • void
  • HttpEntiy<?> 或 ResponseEntity<?>
  • Callable<?>
  • DeferredResult<?>

六、关于日期处理

日期类型不能自动注入到方法的参数中。需要单独做转换处理。使用@DateTimeFormat注解,需要在springmvc.xml配置文件中添加<mvc:annotation-driven/> 标签。

1、在方法的参数中使用@DateTimeFormat注解
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");

@RequestMapping("/myDate")
public String myDate(
        @DateTimeFormat(pattern = "yyyy-mm-dd") Date myDate
        ) {
    String formatTime = dateFormat.format(myDate);
    System.out.println(formatTime);
    return "show";
}
2、在类的成员setXXX()方法上使用@DateTimeFormat注解
@DateTimeFormat(pattern="yyyy-MM-dd")
public void setDate(Date date) {
this.date = date;
}
3、@InitBinder 注解解决类中日期问题
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");
// 注册一个全局的日期处理注解
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
    dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-mm-dd"), true));
}
@RequestMapping("/myDate")
public String myDate(Date myDate) {
    System.out.println(myDate);
    System.out.println(simpleDateFormat.format(myDate));
    return "show";
}
4、关于JSP页面的日期显示

注:日期在JSP页面进行格式化输出时,需要使用的国际化标签(JSTL)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>Show………………………………………………</h2>
    <br><br><br>
    <h2>学生表:</h2>
    <table width="700px" border="1">
        <tr>
            <th>姓名</th>
            <th>生日</th>
        </tr>
        <c:forEach items="${birthdays}" var="stu">
            <tr>
                <td>${stu.name}</td>
                <!-- 通过 <fmt:formatDate>标签,格式化输出日期型数据 -->
                <td>${stu.birthday} --=======-- <fmt:formatDate value="${stu.birthday}" pattern="yyyy年mm月dd日"></fmt:formatDate> </td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

七、<mvc:annotation-driven> 标签的使用

  • <mvc:annotation-driven> 会自动注册两个bean,分别为:DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter,是springmvc为@controller分发请求所必须的。除了注册了这两个bean,还提供了很多支持。
    • 1)支持使用ConversionService实例对表单参数进行类型转换;
    • 2)支持使用@NumberFormat、@DateTimeFormat;
    • 3)注解完成数据类型的格式化;
    • 4)支持使用@RequestBody和@ResponseBody 注解;
    • 5)静态资源的分流也是用该标签。

八、关于将资源防止在WEB-INF目录下

  • 将动态资源放在WEB-INF目录下,可以保证资源的安全性。在WEB-INF目录下的动态资源不可以直接访问,必须要通过请求转发的方式进行访问。这样避免了通过地址栏直接对资源的访问。

Over!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值