【SpringMVC】| SpringMVC注解式开发

- 日理万妓 2024-03-27 10:48 186阅读 0赞

目录

一:SpringMVC注解式开发

  1. @RequestMapping定义请求规则

  2. 五种数据提交的方式

    (1)单个提交数据

(2)对象封装提交数据

(3)动态占位符提交(用的少)【@PathVariable注解】

(4)映射名称不一致(常用)【@RequestParam注解】

(5)手工提取数据(了解)

  1. 请求参数中文乱码解决

  2. action方法的返回值

  3. SpringMVC的四种跳转方式

  4. SpringMVC支持的默认参数类型

  5. 日期处理

(1)日期注入

(2)日期显示

  1. 标签的使用

  2. 资源在WEB-INF目录下


一:SpringMVC注解式开发

1. @RequestMapping定义请求规则

通过@RequestMapping 注解可以定义处理器对于请求的映射规则(此注解就是来映射服务器访问的路径)。该注解可以注解在方法上,也可以注解在类上,意义是不同的。value 属性值常以“/”开始,当value是其唯一属性时,可以省略属性名;@RequestMapping的value 属性用于定义所匹配请求的 URI,以“/”开始。

(1)此注解可加在方法上,是为此方法注册一个可以访问的名称(路径)

前端请求

  1. <%--发送超链接--%>
  2. <a href="${pageContext.request.contextPath}/demo.action">发送请求</a>

后端代码:只有方法上有@RequestMapping注解

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. public class DemoAction {
  6. @RequestMapping("/demo")
  7. public String demo(){
  8. return "main";
  9. }
  10. }

(2)@RequestMapping也可以加在类上,相当于是多了一层路径(虚拟路径),区分不同类中相同的action的名称

注:一般前端发送的请求是${pageContext.request.contextPath}/demo.action,此时我们就只需要在方法上定义@RequestMapping注解,指定路径demo。如果此时发送的请求是${pageContext.request.contextPath}/mvc/demo.action,此时就需要在类上在指定一个@RequestMapping注解取指定前面的路径mvc!

前端请求:多一个mvc路径

  1. <%--发送超链接--%>
  2. <a href="${pageContext.request.contextPath}/mvc/demo.action">发送请求</a>

后端代码:在类上和方法上都有@RequestMapping注解

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. @RequestMapping("/mvc")
  6. public class DemoAction {
  7. @RequestMapping("/demo")
  8. public String demo(){
  9. return "main";
  10. }
  11. }

(3)此注解可区分get请求和post请求

前端请求:提交一个form表单(get和post请求)

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <--发送超链接-->
  8. <form action="${pageContext.request.contextPath}/mvc/demo.action" method="get" />
  9. <form action="${pageContext.request.contextPath}/mvc/demo.action" method="post" />
  10. <input type="submit" value="提交" />
  11. </body>
  12. </html>

后端代码:使用method属性,指定接收的是get请求还是post请求

注:使用@RequestMapping注解的method属性method = RequestMethod.GET或.POST

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RequestMethod;
  5. @Controller
  6. @RequestMapping("/mvc")
  7. public class DemoAction {
  8. @RequestMapping(value = "/demo",method = RequestMethod.GET)
  9. public String demo(){
  10. System.out.println("发送Get请求");
  11. return "main";
  12. }
  13. @RequestMapping(value = "/demo",method = RequestMethod.POST)
  14. public String demo1(){
  15. System.out.println("发送Post请求");
  16. return "main";
  17. }
  18. }

(4) 补充:客户端浏览器常用的请求方式,及其提交方式有以下几种

d92843c860414545ae473a3ba2280567.png

也就是说,只要指定了处理器方法匹配的请求提交方式为 POST请求,则相当于指定了请求发送的方式:要么使用表单请求form要么使用 AJAX请求,其它请求方式被禁用。当然,若不指定 method 属性,则无论是 GET 还是 POST 提交方式,均可匹配!

接下来我们就来分析一下可优化的内容,也就是下面要讲解的知识点:

0bf006dc3d6f411380f6088b836a4558.png

2. 五种数据提交的方式

(1)单个提交数据

后端方法中声明一个和前端表单提交的参数名称相同的参数,由框架按照名称直接注入

前端代码:

  1. <h1>1.单个数据提交</h1>
  2. <form action="${pageContext.request.contextPath}/one.action">
  3. 姓名:<input type="text" name="myname"><br>
  4. 年龄:<input type="text" name="myage"><br>
  5. <input type="submit" value="提交">
  6. </form>

后端代码:

传的参数必须与前面表中的属性名相同,(myage+10)的目的是为了测试进行了自动类型转换,转换成了int类型。

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. public class DataSubmitAction {
  6. @RequestMapping("/one")
  7. // 方法中的参数与form表单中name属性的值是相同的---按照名字注入
  8. public String one(String myname,int myage){
  9. System.out.println("myname="+myname+",myage="+(myage+10));
  10. return "main";
  11. }
  12. }

执行结果:

2acbd1ccce1c430688d8951271ac83a0.png

核心:

①表中form中的属性,例如:myname和myage的属性名与action方法参数的名称一致!

②这样就可以完成自动注入值,并且可以自动进行类型的转换!

补充:那如果使用了复选框呢?一个name对应多个value!

回顾:如果使用原生的Servlet的request对象调用getParameter方法获取单个值,如果是多个值,使用getParameter方法只能获取到多个值的第一个值;此时就需要getParameters方法就可以获取多个值。那么SpringMVC怎么处理呢?

前端请求:

  1. <form th:action="@{/testcheckbox}">
  2. 爱好<input type="checkbox" name="lovers" value="smoking">smoking</input>
  3. <input type="checkbox" name="lovers" value="tangtou">tangtou</input>
  4. <input type="checkbox" name="lovers" value="drink">drink</input>
  5. <input type="submit" value="爱好"/>
  6. </form>

方法1:直接使用String类型,会把多个值使用逗号拼接在一起!

  1. @RequestMapping("/testcheckbox")
  2. public String lovers(String lovers){
  3. System.out.println(lovers);
  4. return "success";
  5. }

执行结果

51d6ccbec44b4a3e9c649d3403fd3bca.png

方法2:也可以使用一个String类型的数组进行接收

注:此时需要调用工具类Arrays的toString方法,把数组以字符串的形式展现出来

  1. @RequestMapping("/testcheckbox")
  2. public String lovers(String[] lovers){
  3. System.out.println(Arrays.toString(lovers));
  4. return "success";
  5. }

执行结果

fc605a96d4cc456ca5bf0d7fe490f07d.png

(2)对象封装提交数据

在方法中声明一个自定义的实体类参数框架调用实体类中相应的setter方法注入属性值,只要保证实体类中成员变量的名称与提交请求的name属性值一致即可。

定义实体类:

  1. package com.bjpowernode;
  2. public class User {
  3. private String name;
  4. private int age;
  5. public User() {
  6. }
  7. public User(String name, int age) {
  8. this.name = name;
  9. this.age = age;
  10. }
  11. @Override
  12. public String toString() {
  13. return "User{" +
  14. "name='" + name + '\'' +
  15. ", age=" + age +
  16. '}';
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public int getAge() {
  25. return age;
  26. }
  27. public void setAge(int age) {
  28. this.age = age;
  29. }
  30. }

前端代码:

  1. <h1>2.对象封装数据提交</h1>
  2. <form action="${pageContext.request.contextPath}/two.action">
  3. 姓名:<input type="text" name="name"><br>
  4. 年龄:<input type="text" name="age"><br>
  5. <input type="submit" value="提交">
  6. </form>

后端代码:

这里传的参数不再是表单中的属性名称,我们借用了实体类User,所以参数就是实体类User

  1. @RequestMapping("/two")
  2. public String two(User user){
  3. System.out.println(user);
  4. return "main";
  5. }

执行结果:

07169d527e4b4eaa87b9aedd71e1537e.png

核心:

①在提交请求中,保证请求参数的名称与实体类中成员变量的名称一致,则可以自动创建对象、可以自动提交数据、自动类型转换、自动封装数据到对象中。

②方法的参数不再是零散的数据,而是我们封装好的实体类User对象。

(3)动态占位符提交(用的少)【**@PathVariable注解**】

仅限于超链接地址栏提交数据,它是一杠一值(前端传数据)一杠一大括号(后端接收数据),使用注解@PathVariable(路径变量)来解析。

前端代码:

先回忆以前的提交方式,使用?与&的方式,例如:uri/?name=value&name=value的方式

  1. <a href="${pageContext.request.contextPath}/three.action?name=张三&age=20" />

现在使用一杠一值的方式,注意位置是在three.action中间:“three“后面或者说“.action”的前面注意最后一个数据后面就不需要斜杠了!

  1. <h1>3.动态占位符数据提交</h1>
  2. <a href="${pageContext.request.contextPath}/three/王五/20.action" />

后端代码:

①前端使用一杠一值传,只是传值,并没有传变量名后端在RequestMapping注解的鎏金后面使用一杠一大括号接收,里面的参数名随意,但是需要@PathVariable注解

若地址栏中RequestMapping注解大括号里{}的变量与下面方法的变量保持一致,此时路径变量@PathVariable注解中的value属性就可以省略;若变量没有保持一致,就需要使用路径变量@PathVariable的value属性指定上面地址栏大括号里的变量

  1. @RequestMapping("/three/{myname}/{myage}")
  2. public String three(@PathVariable String myname, @PathVariable int myage){
  3. System.out.println("myname="+myname+",myage="+(myage+10));
  4. return "main";
  5. }

执行结果:

495934852690431e8878c8ea11f34900.png

核心:

①前端使用一杠一值的形式提交,后端使用一杠一大括号的形式接收,这里大括号里面的参数随意

②方法中的参数需要使用@PathVariable注解,没有任何属性,这是参数和下面方法中的参数一致

③假如参数不一致,@PathVariable注解就需要带上上面@RequestMapping注解中的参数(这两个要保持一致);例如:

097bdb784d41400890f6bc1d28382a25.png

(4)映射名称不一致(常用)【**@RequestParam注解**】

前面单个提交数据中提到前端的属性名必须与后端方法中的属性名保持一致,但是在实际开发中我们并不知道前端用什么样的属性名;当**form表单中提交请求参数与action方法的形参的名称不一致,使用注解@RequestParam**来解析!

前端代码:

前端提交的数据,name属性的值是name和age

  1. <h1>4.映射名称不一致</h1>
  2. <form action="${pageContext.request.contextPath}/four.action">
  3. 姓名:<input type="text" name="name"><br>
  4. 年龄:<input type="text" name="age"><br>
  5. <input type="submit" value="提交">
  6. </form>

后端代码:

后端接收数据,方法中的属性名称是myname和myage,名称不一致,如何解决?使用@RequestParam注解

  1. @RequestMapping("/four")
  2. public String four(@RequestParam("name") String myname, @RequestParam("age") int myage){
  3. System.out.println("myname="+myname+",myage="+(myage+10));
  4. return "main";
  5. }

执行结果:

0b8455c9cc3a4427aff8f7fa5d7bd8a7.png

核心:

①前端提交数据的表单,属性名我们可能不知道;后端我们编写代码方法中的属性又是根据我们自己的意愿编写,怎么让两者之间建立联系?使用@RequestParam注解即可。

②@RequestParam是将请求参数和控制器方法的形参创建映射关系,实际上@RequestParam注解一共有三个属性:

value:指定为形参赋值的请求参数的参数名,和name属性互为别名。

required:设置是否必须传输此请求参数,默认值为true。若设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则页面报错400:Required String parameter ‘xxx’ is not present;若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null

defaultValue:不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为空字符串””时,则使用defaultValue赋的默认值为形参赋值!

补充:@RequestHeader注解和@CookieValue注解

@RequestHeader注解

①@RequestHeader是将请求头信息和控制器方法的形参创建映射关系。

②@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam。

前端代码

注:斜杠其实就会被解析为localhost:8080

  1. <a th:href="@{/testRequesthearder}">测试RequestHeader注解</a>

后端代码

注:通过RequestHeader注解的Host属性就可以拿到请求头localhost

  1. @RequestMapping("/testRequesthearder")
  2. public String testRequesthearder(@RequestHeader("Host") String host){
  3. System.out.println(host);
  4. return "success";
  5. }

@CookieValue注解

①@CookieValue是将cookie数据和控制器方法的形参创建映射关系。

②@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam。

注:当前是html并没有Cookie,如果是JSP就有(九大内置对象之一)。并且session是依赖于Coookie的Cookie是客户端的会话技术,Session是服务器端的会话技术。当我们调用getSession方法时就会创建一个键位session的Cookie。

前端代码

①第一次发出请求(去调用getSession方法创建session),此时Cookie应该是存在响应报文的

解释:此时创建一个Cookie对象,它的键就是JSESSIONID是固定值,值是一个随机序列。然后Session对象会以这个随机序列为key,创建的session对象为value存储到Map集合当中。从这里也能看出session是依赖于cookie的!

3d03df5207d342cd9e6a501fc4c04fcb.png

②再次发出请求,就会存在于请求报文中

1656856f3c7d46f6843696d2e115a2ba.png

  1. <a th:href="@{/testRequestcookie}">测试RequestCookie注解</a>

后端代码

  1. @RequestMapping("/testRequestcookie")
  2. public String testRequestcookie(HttpServletRequest request,
  3. @CookieValue("JSESSIONID") String JSESSIONID ){
  4. // 创建session对象(会去创建一个cookie)
  5. HttpSession session = request.getSession();
  6. System.out.println("JSESSIONID:"+JSESSIONID);
  7. return "success";
  8. }

执行结果

7be42f1ddd704d219190223efcce06f9.png

(5)手工提取数据(了解)

使用原始ServletAPI的方式:在方法参数中声明一个HttpServletRequest request对象,使用request的getParameter()获取表单提交的数据,这样得到的数据还要根据自己需要的类型手工进行数据类型的转换。

前端代码:

  1. <h1>5.手工提交</h1>
  2. <form action="${pageContext.request.contextPath}/five.action">
  3. 姓名:<input type="text" name="name"><br>
  4. 年龄:<input type="text" name="age"><br>
  5. <input type="submit" value="提交">
  6. </form>

后端代码:

此时方法中的参数HttpServletRequest对象,可以拿来直接用;然后调用getParameter方法根据key获取对应的value值。

注:从请求中得到的数据都是String类型,要想得到其它类型需要进行手动转换。

  1. @RequestMapping("/five")
  2. public String five(HttpServletRequest request){
  3. // 根据key获取value
  4. String name = request.getParameter("name");
  5. // 需要手动转换为int类型
  6. int age = Integer.parseInt(request.getParameter("age"));
  7. System.out.println("name="+name+",age="+(age+10));
  8. return "main";
  9. }

执行结果:

c939203e89ff4f65829084969103f9d0.png

核心:

①方法的参数传一个HttpServletRequest对象,不需要创建直接可以使用,然后调用getParameter方法获取到value;想要其它类型的数据还需要自己手动进行转换。

3. 请求参数中文乱码解决

(1)对于前面所接收的请求参数,若是Post请求,并含有中文,则会出现中文乱码问题。Spring对于请求参数中的中文乱码问题,给出了专门的字符集过滤器:spring-web-5.2.5.RELEASE.jar 的org.springframework.web.filter 包下的 CharacterEncodingFilter

(2)在web.xml中配置过滤器CharacterEncodingFilter,建议一开始就放在最前面!

注:对于高版本的Tomcat已经解决了get请求中文乱码问题,如果还是乱码,青岛Tomcat的cong文加夹下设置server.xml文件

  1. <Connector port="8080" URIEncoding="UTF-8" protocol="HTTP/1.1"
  2. connectionTimeout="20000"
  3. redirectPort="8443" />

(1)解决方案

注:以前都是使用request.setCharacterEncoding设置UTF-8,先不说有没有request对象。在获取到请求参数之后在设置字符编码是没用的,实际上在发出请求时DispatcherServlet已经先获取到请求参数,所以就算设置了也没用!

解决方案:在 web.xml配置中注册字符集过滤器(Servlet的三大组件:监听器、过滤器、Servlet),即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前,因为过滤器的执行是按照其注册顺序进行的。

  1. <!--注册过滤器:解决post请求乱码问题-->
  2. <filter>
  3. <filter-name>encode</filter-name>
  4. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  5. <!--指定字符集-->
  6. <init-param>
  7. <param-name>encoding</param-name>
  8. <param-value>UTF-8</param-value>
  9. </init-param>
  10. <!--强制request使用字符集encoding-->
  11. <init-param>
  12. <param-name>forceRequestEncoding</param-name>
  13. <param-value>true</param-value>
  14. </init-param>
  15. <!--强制response使用字符集encoding-->
  16. <init-param>
  17. <param-name>forceResponseEncoding</param-name>
  18. <param-value>true</param-value>
  19. </init-param>
  20. </filter>
  21. <filter-mapping>
  22. <filter-name>encode</filter-name>
  23. <url-pattern>/*</url-pattern>
  24. </filter-mapping>

(2)CharaterEncodingFilter源码分析

三个参数:编码方式encodingforceRequestEncodingforceResponseEncoding默认值都是false

af131c2010624103887adcb594cbc466.png

所在在配置中设置encoding值为UTF-8,另外两个参数设置成true后,会走以下代码

10e64dfdc3e6449488f068f13a097219.png

4. action方法的返回值

(1)String:客户端资源的地址,自动拼接前缀和后缀,还可以屏蔽自动拼接字符串,可以指定返回的路径。
(2)Object(包括对象和集合):返回json格式的对象自动将对象或集合转为json使用jackson工具进行转换,必须要添加jackson依赖,一般用于ajax请求。
(3)void:无返回值,一般用于ajax请求。
(4)基本数据类型:用于ajax请求。
(5)ModelAndView:返回数据和视图对象,现在用的很少

需求:完成ajax请求访问服务器,返回学生集合
第一步:增加jackson依赖

  1. <!--添加jackson依赖-->
  2. <dependency>
  3. <groupId>com.fasterxml.jackson.core</groupId>
  4. <artifactId>jackson-databind</artifactId>
  5. <version>2.9.8</version>
  6. </dependency>

第二步:springmvc配置

注:ajax请求不需要视图解析器(InternalResourceViewResolver),发送的是ajax请求,哪里来回到哪里去,但是需要添加注解驱动,这个注解驱动是用来解析@ResponseBody注解

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:mvc="http://www.springframework.org/schema/mvc"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
  7. <!--包扫描-->
  8. <context:component-scan base-package="com.bjpowernode.controller"/>
  9. <!--添加注解驱动,专门处理ajax请求-->
  10. <mvc:annotation-driven/>
  11. </beans>

第三步:web.xml配置

配置解决中文乱码问题和注册springmvc!

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <!--注册过滤器:解决post请求乱码问题-->
  7. <filter>
  8. <filter-name>encode</filter-name>
  9. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  10. <!--指定字符集-->
  11. <init-param>
  12. <param-name>encoding</param-name>
  13. <param-value>utf-8</param-value>
  14. </init-param>
  15. <!--强制request使用字符集encoding-->
  16. <init-param>
  17. <param-name>forceRequestEncoding</param-name>
  18. <param-value>true</param-value>
  19. </init-param>
  20. <!--强制response使用字符集encoding-->
  21. <init-param>
  22. <param-name>forceResponseEncoding</param-name>
  23. <param-value>true</param-value>
  24. </init-param>
  25. </filter>
  26. <filter-mapping>
  27. <filter-name>encode</filter-name>
  28. <url-pattern>/*</url-pattern>
  29. </filter-mapping>
  30. <!--注册springmvc-->
  31. <servlet>
  32. <servlet-name>springmvc</servlet-name>
  33. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  34. <init-param>
  35. <param-name>contextConfigLocation</param-name>
  36. <param-value>classpath:springmvc.xml</param-value>
  37. </init-param>
  38. </servlet>
  39. <servlet-mapping>
  40. <servlet-name>springmvc</servlet-name>
  41. <url-pattern>*.action</url-pattern>
  42. </servlet-mapping>
  43. </web-app>

第四步:在webapp目录下新建js目录,添加jQuery函数库,在index.jsp页面上导入函数库

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. <%--引入JQuery库--%>
  6. <script src="js/jquery-3.3.1.js"></script>
  7. </head>
  8. <body>
  9. <a href="javascript:showStu()">访问服务器返回学生集合</a>
  10. <div id="mydiv">等待服务器返回数据</div>
  11. <script type="text/javascript">
  12. // 使用JQuery封装的ajax()方法发送请求
  13. $.ajax({
  14. url:"${pageContext.request.contextPath}/list.action",
  15. type:"get",
  16. dataType:"json",
  17. success:function (stuList){
  18. var s = "";
  19. $.each(stuList,function (i,stu) {
  20. s += stu.name + "---"+stu.age+"<br>";
  21. });
  22. // 回显数据到div
  23. $("#mydiv").html(s);
  24. }
  25. });
  26. </script>
  27. </body>
  28. </html>

Student类:因为上面是要返回学生集合

  1. package com.bjpowernode.pojo;
  2. public class Student {
  3. private String name;
  4. private int age;
  5. public Student() {
  6. }
  7. public Student(String name, int age) {
  8. this.name = name;
  9. this.age = age;
  10. }
  11. @Override
  12. public String toString() {
  13. return "Student{" +
  14. "name='" + name + '\'' +
  15. ", age=" + age +
  16. '}';
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public int getAge() {
  25. return age;
  26. }
  27. public void setAge(int age) {
  28. this.age = age;
  29. }
  30. }

第五步:服务器端代码

注:@ResponseBody的作用:其实是将java对象转为json格式的数据,使用就是专门用来处理@ResponseBody注解的!

注:发送ajax请求一定要使用@ResponseBody注解!

  1. package com.bjpowernode.controller;
  2. import com.bjpowernode.pojo.Student;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. @Controller
  9. public class StudentListAction {
  10. @RequestMapping("/list")
  11. @ResponseBody // 处理ajax一定要加@ResponseBody注解
  12. public List<Student> list(){
  13. List<Student> list = new ArrayList<>();
  14. // 添加数据
  15. Student stu1 = new Student("张三", 18);
  16. Student stu2 = new Student("李四", 19);
  17. Student stu3 = new Student("王五", 20);
  18. list.add(stu1);
  19. list.add(stu2);
  20. list.add(stu3);
  21. // 实际上SpringMVC框架会将list集合自动转为json数组
  22. return list;
  23. }
  24. }

第六步:测试

点击超链接前

ec34b024e3e64c6dbcf1a19b85ab8fc6.png

点击超链接后

ebbb46b0df434dc7889d672418e58787.png

5. SpringMVC的四种跳转方式

默认的跳转是请求转发,直接跳转到jsp页面展示。

①还可以使用框架提供的关键字redirect:,进行一个重定向操作,包括重定向页面和重定向action。

②使用框架提供的关键字forward:,进行服务器内部转发操作,包括转发页面和转发action。

注:当使用【redirect:】和【forward:】关键字时,视图解析器中前缀后缀的拼接就无效了。

首先我们先通过一张图区分一下转发和重定向:

我们也可以通过一个生活中的例子来理解:有三个人你、我、他

转发:你给我打电话问事情,我不知道,我把我的电话给了身边的他;但是本质上还是我的电话,显示的地址就是我的地址:http://localhost:8080/one.action

重定向:你给我打电话问事情,我不知道,把电话挂了;你重新给他打电话进行询问,所以本质是他的电话,显示的地址就是他的地址:http://localhost:8080/main.jsp

5e883f67f9d5408b88f43eee27c31eb0.png

(1)请求转发的跳转代码

index.jsp:

两种转发方式,一种是我们前面一直用的,默认的跳转方式;另一种是跳转到其它的action

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <br>
  8. <a href="${pageContext.request.contextPath}/one.action">1.请求转发页面(默认)</a>
  9. <a href="${pageContext.request.contextPath}/two.action">2.请求转发action</a>
  10. </body>
  11. </html>

Other.action:第二种跳转到其它action,肯定需要定义一个其它的action

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. public class OtherAction {
  6. @RequestMapping("/other")
  7. public String other(){
  8. System.out.println("这是other的action访问........");
  9. return "main";
  10. }
  11. }

测试:

解释forward:是屏蔽视图解析器中前缀和后缀的拼接;

如果没有forward:,最终展现的结果就是admin/other.action!

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. public class JumpAction {
  6. @RequestMapping("/one")
  7. public String one(){
  8. // 默认使用视图解析器拼接前缀和后缀进行页面跳转
  9. System.out.println("这是请求转发页面跳转........");
  10. return "main";
  11. }
  12. @RequestMapping("/two")
  13. public String two(){
  14. // 使用forward:可以屏蔽前后缀的拼接
  15. return "forward:/other.action";
  16. }
  17. }

结果1:请求转发页面是从index.jsp—->one.action—->main.jsp,最终地址是one.action的地址

655d4f50e22647cc9fb582b1cb9528b5.png

结果2:请求转发页面是从index.jsp—->two.action—->other.action—->main.jsp,最终地址是two.action的地址

d3dcbbecd40342a5b317f7e0c72c1023.png

结论:最终的地址都是第一次页面跳转的地址,与前面我们分析的一致!

(2)重定向的跳转代码

index.jsp:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <br>
  8. <a href="${pageContext.request.contextPath}/three.action">1.重定向页面</a><br>
  9. <a href="${pageContext.request.contextPath}/four.action">2.重定向action</a><br>
  10. </body>
  11. </html>

测试:

解释redirect:也是屏蔽视图解析器中前缀和后缀的拼接;无论是重定向页面还是重定向其它action,都要使用redirect。

注:重定向页面时需要写上页面的绝对路径,例如:redirect:/admin/main.jsp,对于重定向其它action和转发相似。

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. public class JumpAction {
  6. @RequestMapping("/three")
  7. public String three(){
  8. // 屏蔽视图解析器拼接前缀和后缀进行页面跳转
  9. System.out.println("这是重定向页面跳转........");
  10. return "redirect:/admin/main.jsp";
  11. }
  12. @RequestMapping("/four")
  13. public String four(){
  14. // 屏蔽视图解析器拼接前缀和后缀进行页面跳转
  15. System.out.println("这是重定向其它action........");
  16. return "redirect:/other.action";
  17. }
  18. }

结果1:从index.jsp—->three.action,发现是重定向到main.jsp,所以是又重新发出请求从index.jsp

-—>main.jsp,最终地址是main.jsp的地址

2971e36254514287baa0d60779e52511.png

结果2:先从index.jsp—->four.action,发现是是重定向到other.action,

所以是又重新发出请求从index.jsp—->other.action,然后other.action又是转发到main.jsp,最终地址是other.action的地址

2709f03a96ca4c448fc688eddf6a4c53.png

结论:最终的地址是最后一次重定向的地址,与前面我们分析的一致!

注:我们也可以利用forword和redirect随便跳转页面,后面跟绝对路径即可;但是转发可以携带数据,重定向不能携带数据(容易数据丢失);并且转发是只能在服务器内部转发,重定向可以访问外部资源!

6. SpringMVC支持的默认参数类型

这些类型不需要创建,只要写在方法参数中就可以使用了(常见的)

(1)HttpServletRequest 对象

(2)HttpServletResponse 对象

(3)HttpSession 对象

(4)Model/ModelMap 对象 

(5)Map对象

注意:Map、Model、ModelMap和request一样,都使用请求作用域进行数据传递,所以服务器端的跳转必须是请求转发,这样才能携带数据。

index.jsp页面,也可以携带数据

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <br><br><br>
  8. <a href="${pageContext.request.contextPath}/data.action?data=李四">访问服务器,进行数据携带跳转</a><br>
  9. </body>
  10. </html>

DataAction类,存入数据

  1. package com.bjpowernode.controller;
  2. import com.bjpowernode.pojo.Student;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.ui.Model;
  5. import org.springframework.ui.ModelMap;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import javax.servlet.http.HttpSession;
  10. import java.util.Map;
  11. @Controller
  12. public class DataAction {
  13. @RequestMapping("/data")
  14. public String data(HttpServletRequest request,
  15. HttpServletResponse response,
  16. HttpSession session,
  17. Model model,
  18. Map map,
  19. ModelMap modelMap
  20. ){
  21. // 创建一个数据
  22. Student stu = new Student("张三", 22);
  23. // 传递数据
  24. request.setAttribute("requestStu",stu);
  25. session.setAttribute("sessionStu",stu);
  26. model.addAttribute("modelStu",stu);
  27. map.put("mapStu",stu);
  28. modelMap.addAttribute("modelMapStu",stu);
  29. return "main";
  30. }
  31. }

跳转到main.jsp取出数据

注:取数据,可以从DataAction类中取出存入的数据;也可以直接从index.jsp中取出携带的数据,但是需要使用 “param.” 的方式!

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <%--取出数据--%>
  8. requestStu对应数据:${requestStu}<br>
  9. sessionStu对应数据:${sessionStu}<br>
  10. modelStu对应数据:${modelStu}<br>
  11. mapStu对应数据:${mapStu}<br>
  12. modelMapStu对应数据:${modelMapStu}<br>
  13. 从index.jsp页面中来的数据:${param.data}
  14. </body>
  15. </html>

测试结果:都能正常取出数据

73dc5edd35a34b13b2b0045622e3170f.png

注意:如果使用重定向呢?

注:如果使用重定向,只有session域的数据还在,其它数据都会丢失!

ad71e827ed0d4513b8a4ac512f47a554.png

执行结果:

8fcaa62efb1243a180f12efac30e4783.png

7. 日期处理

日期类型不能自动注入到方法的参数中,需要单独做转换处理。

(1)日期注入

第一种情况:单个日期注入【**@DateTimeFormat**】

使用注解的方式对日期进行格式化:@DateTimeFormat此注解必须搭配springmvc.xml文件中的开启注解驱动标签一起使用!

index.jsp中表单提交日期格式的字符串

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <form action="${pageContext.request.contextPath}/mydate.action">
  8. 日期:<input type="date" name="mydate">
  9. <input type="submit" value="提交">
  10. </form>
  11. </body>
  12. </html>

springmvc.xml中添加注解驱动

  1. <!--添加注解驱动-->
  2. <mvc:annotation-driven />

MyDateAction程序

①@DateTimeFormat(pattern = “yyyy-MM-dd”)是把提交过来的字符串转换为日期格式;

②new SimpleDateFormat(“yyyy-MM-dd”)是为了格式化日期;

  1. package com.bjpowernode.controller;
  2. import org.springframework.format.annotation.DateTimeFormat;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import java.text.SimpleDateFormat;
  6. import java.util.Date;
  7. @Controller
  8. public class MyDateAction {
  9. // 用来格式化日期
  10. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  11. @RequestMapping("/mydate")
  12. public String MyDate(@DateTimeFormat(pattern = "yyyy-MM-dd") Date mydate){
  13. // 未格式化的日期
  14. System.out.println(mydate);
  15. // 格式化的日期
  16. System.out.println(sdf.format(mydate));
  17. return "main";
  18. }
  19. }

执行结果:

105252731f634f63b6a9034b5e57c0a0.png

第二种情况:类中全局日期处理【**@InitBinder注解**】

注册一个@InitBinder注解,用来解析本类中所有的日期类型,自动转换!

  1. package com.bjpowernode.controller;
  2. import org.springframework.beans.propertyeditors.CustomDateEditor;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.WebDataBinder;
  6. import org.springframework.web.bind.annotation.InitBinder;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import java.text.SimpleDateFormat;
  9. import java.util.Date;
  10. @Controller
  11. public class MyDateAction {
  12. // 用来格式化日期
  13. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  14. // 注册一个全局的日期处理注解,进字符串转换成日期格式
  15. @InitBinder
  16. public void initBinder(WebDataBinder dataBinder){
  17. dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,true));
  18. }
  19. @RequestMapping("/mydate")
  20. public String MyDate(Date mydate){
  21. System.out.println(sdf.format(mydate));
  22. return "main";
  23. }
  24. }

核心代码解析:

WebDataBinder参数表示数据绑定,表示所有的数据都可以通过它进行绑定!

调用registerCustomEditor方法表示自定义一个转换器:

第一个参数是要转换的类型:Date.class

第二个参数是使用什么工具去转?

创建一个CustomDateEditor对象:一个参数是格式化的日期的sdf,另一个参数是boolean类型,true表示日期为空也不报错。

  1. // 注册一个全局的日期处理注解,下面这个方法需要自己编写
  2. @InitBinder
  3. public void initBinder(WebDataBinder dataBinder){
  4. dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,true));
  5. }

补充:如果日期作为成员变量,例如在User类当中有一个属性是Date,那么既可以在属性上使用@DateTimeFormat注解,也可以在对应的set方法setDate上面使用@DateTimeFormat注解

71fd2c077fd3431c8f68c65703a55dc9.png

(2)日期显示

第一种情况:单个数据显示

单个日期传递很简单,从前端获取,直接格式化好以后,放到request域当中即可

传数据

  1. package com.bjpowernode.controller;
  2. import org.springframework.beans.propertyeditors.CustomDateEditor;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.WebDataBinder;
  6. import org.springframework.web.bind.annotation.InitBinder;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import javax.servlet.http.HttpServletRequest;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. @Controller
  12. public class MyDateAction {
  13. // 用来格式化日期
  14. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  15. // 注册一个全局的日期处理注解
  16. @InitBinder
  17. public void initBinder(WebDataBinder dataBinder){
  18. dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,true));
  19. }
  20. // 存入数据
  21. @RequestMapping("/mydate")
  22. public String MyDate(Date mydate, HttpServletRequest request){
  23. // 格式化以后放到request域当中,传过去的实际上是日期格式的字符串
  24. request.setAttribute("mydate",sdf.format(mydate));
  25. return "showdate";
  26. }
  27. }

取数据

注:再次强调,如果取出action中的数据直接使用${变量名}就可以取出来;如果取出来的是其它.jsp网页的数据需要使用param,${para.变量名}

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. 单个日期提交数据:${mydate}
  8. </body>
  9. </html>

第二种情况:实体类对象的成员变量是日期类型

如果是list集合当中的实体类对象的成员变量是日期类型,则必须使用JSTL标签库进行显示,使用JSTL的步骤:

①添加依赖

②在页面上导入标签库

③使用标签遍历显示数据

先创建一个User类

  1. package com.bjpowernode.pojo;
  2. import java.util.Date;
  3. public class User {
  4. private String name;
  5. // 实体类当中含有Date类型
  6. private Date birth;
  7. public User() {
  8. }
  9. public User(String name, Date birth) {
  10. this.name = name;
  11. this.birth = birth;
  12. }
  13. @Override
  14. public String toString() {
  15. return "User{" +
  16. "name='" + name + '\'' +
  17. ", birth=" + birth +
  18. '}';
  19. }
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. public Date getBirth() {
  27. return birth;
  28. }
  29. public void setBirth(Date birth) {
  30. this.birth = birth;
  31. }
  32. }

index.jsp

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <a href="${pageContext.request.contextPath}/list.action">显示集合对象的日期成员</a>
  8. </body>
  9. </html>

存入数据

  1. package com.bjpowernode.controller;
  2. import com.bjpowernode.pojo.User;
  3. import org.springframework.beans.propertyeditors.CustomDateEditor;
  4. import org.springframework.format.annotation.DateTimeFormat;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.web.bind.WebDataBinder;
  7. import org.springframework.web.bind.annotation.InitBinder;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import javax.servlet.http.HttpServletRequest;
  10. import java.text.ParseException;
  11. import java.text.SimpleDateFormat;
  12. import java.util.ArrayList;
  13. import java.util.Date;
  14. import java.util.List;
  15. @Controller
  16. public class MyDateAction {
  17. // 用来格式化日期
  18. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  19. @RequestMapping("/list")
  20. public String list(HttpServletRequest request) throws ParseException {
  21. User u1 = new User("张三", sdf.parse("1999-01-01"));
  22. User u2 = new User("李四", sdf.parse("1999-02-02"));
  23. User u3 = new User("王五", sdf.parse("1999-03-03"));
  24. List<User> list = new ArrayList<>();
  25. list.add(u1);
  26. list.add(u2);
  27. list.add(u3);
  28. // 放到request当中
  29. request.setAttribute("userList",list);
  30. return "showdate";
  31. }
  32. }

获取数据

①添加JSTL依赖

  1. <dependency>
  2. <groupId>javax.servlet</groupId>
  3. <artifactId>jstl</artifactId>
  4. <version>1.2</version>
  5. </dependency>

②在页面上导入标签库

  1. <%--导入jstl核心标签库--%>
  2. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <%--导入jstl格式化标签库--%>
  4. <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

③使用标签格式化和遍历显示数据

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. <%--导入jstl核心标签库--%>
  6. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  7. <%--导入jstl格式化标签库--%>
  8. <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  9. </head>
  10. <body>
  11. 单个日期提交数据:${mydate}
  12. <br><br>
  13. <h2>学生集合</h2>
  14. <table width="50%" border="1px">
  15. <tr>
  16. <th>姓名</th>
  17. <th>生日</th>
  18. </tr>
  19. <c:forEach items="${userList}" var="user">
  20. <tr>
  21. <td>${user.name}</td>
  22. <td><fmt:formatDate value="${user.birth}" pattern="yyyy-MM-dd"></fmt:formatDate> </td>
  23. </tr>
  24. </c:forEach>
  25. </table>
  26. </body>
  27. </html>

执行结果:

6085ee52b98f453bbca9b4bc6444c3e6.png

补充:JSON中的日期显示

需要在类中的成员变量的getXXX方法上加@JsonFormat注解

d8462f7a5c44460ab9255d6f3e050d94.png

8. 标签的使用

前言:目前我们发送ajax请求【@ReponseBody注解处理Json】日期转换【@TimeDateFormat处理日期】都使用了这个标签,功能很强大!

实际上:会自动注册两个bean(俩个帮手),分别为DefaultAnnotationHandlerMapping**和AnnotationMethodHandlerAdapter**。是springmvc为@controller分发请求所必须的,除了注册了这两个bean,还提供了很多支持。

(1)支持使用ConversionService 实例对表单参数进行类型转换;

(2)支持使用 @NumberFormat 、@DateTimeFormat;

(3)注解完成数据类型的格式化;

(4)支持使用 @RequestBody 和 @ResponseBody 注解;

(5)静态资源的分流也使用这个标签;

9. 资源在WEB-INF目录下

(1)将动态资源放在WEB-INF目录下,这样可以保证资源的安全性;在WEB-INF目录下的动态资源不可以直接访问,必须要通过【请求转发】的方式进行访问。这样避免了通过地址栏直接对资源的访问,【重定向也无法访问动态资源】

第一步:在WEB-INF目录下创建一个jsp目录,在目录下创建index.jsp和main.jsp

fd91f02b2b49429db241d7bb46381830.png

开启Tomcat服务器,使用路径直接访问,根本访问不到,更安全了

c212f934eb86428687ad016231152bd7.png

第二步:只能通过请求转发的方式进行访问

WebInfAction程序

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. public class WebInfAction {
  6. @RequestMapping("/showIndex")
  7. public String showIndex(){
  8. System.out.println("访问index.jsp页面");
  9. return "index";
  10. }
  11. @RequestMapping("/showMain")
  12. public String showMain(){
  13. System.out.println("访问main.jsp页面");
  14. return "main";
  15. }
  16. }

需要地址的拼接,所以springmvc.xml中也要修改视图解析器的前缀

  1. <!--视图解析器-->
  2. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  3. <!--<property name="prefix" value="/admin/"></property>-->
  4. <property name="prefix" value="/WEB-INF/jsp/"></property>
  5. <property name="suffix" value=".jsp"></property>
  6. </bean>

第三步:进行测试,直接输入地址栏,通过转发的方式,可以正常访问

d5e8521250dc4368933d489fc474a168.png

注:这样就相当于把index.jsp和main.jsp保护起来了,不能直接访问,要想访问必须通过WebInfAction才可以

(2)去掉后缀action的访问

修改web.xml,把标签的路径修改为【“/”】,表示拦截所有的请求;优先访问的是没有后缀的,然后再去访问带.jsp或.action的

  1. <servlet-mapping>
  2. <servlet-name>springmvc</servlet-name>
  3. <!-- <url-pattern>*.action</url-pattern>-->
  4. <url-pattern>/</url-pattern>
  5. </servlet-mapping>

测试:以后访问就可以不需要后缀直接访问

595deb5a19bc454096908891c0aef692.png

缺点:知道http://localhost:8080/web-inf/showIndex这个地址也能直接访问到,所以就需要增加一个权限验证功能。

(3)登录页面处理:登录成功才让你访问,登录失败打回原始的登录页面

增加login.jsp登录页面

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <form action="${pageContext.request.contextPath}/login">
  8. 姓名:<input type="text" name="name"><br>
  9. 密码:<input type="password" name="pwd"><br>
  10. <input type="submit" value="登录">
  11. </form>
  12. </body>
  13. </html>

WebInfAction中做登录判断

  1. package com.bjpowernode.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import javax.servlet.http.HttpServletRequest;
  5. @Controller
  6. public class WebInfAction {
  7. // 首先要跳转到登录页面
  8. @RequestMapping("/showLogin")
  9. public String submit(){
  10. System.out.println("访问login.jsp进行登录");
  11. return "login";
  12. }
  13. // 跳转到login.jsp后,在进行判断
  14. @RequestMapping("/login")
  15. public String login(String name, String pwd, HttpServletRequest request){ // 与前端保持一致,提交的数据自动吸过来
  16. // 进行判断,equalsIgnoreCase忽略大小写
  17. if ("root".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
  18. // 登录成功,可以访问main.jsp
  19. return "main";
  20. }else {
  21. // HttpServletRequest是用来提示登录失败的信息
  22. request.setAttribute("msg","用户名或者密码不正确");
  23. // 登录失败,跳转到登录页面login.jsp,在login.jsp中${msg}打印这个提示错误的信息
  24. return "login";
  25. }
  26. }
  27. }

登录失败:会有提示,并且保持原来的登录页面

b71c877afc2547f680a4546fc17c2d9d.png

登录成功:正常跳转访问

ff79fe200e244c6481fb67eb3a341c58.png

存在的问题:还是同样的道理,假如我们知道main.jsp的路径,直接在地址栏上输出进行访问也可以,根本就不需要登录,所以此时的登录页面就是一个摆设;这就需要我们接下来学习拦截器!

20009bb1805d4399895e7f13f75b068b.png

发表评论

表情:
评论列表 (有 0 条评论,186人围观)

还没有评论,来说两句吧...

相关阅读

    相关 04_springmvc注解开发

    一.注解开发 **需求:**1、进入商品查询列表页面。    2、点击修改,进入商品修改页面,页面中显示了要修改的商品(从数据库查询),要修改的商品从数据库查询,根...