微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

2021-08-02 SpringMVC实战技术

一、MVC软件框架与SpringMVC介绍

1.1 MVC模式

MVC模式是一种开发方式,它的主要用途是对组件之间进行隔离分层。

1.1.1 MVC三层架构

  1. M(odel)模型,包含被传递的数据。在软件项目中,M常常被定义为业务模型,也就是业务/服务层。
  2. V(ison)视图层,即用什么组件显示数据,常用的有HTML与JSP这些文件
  3. C(ontroller)控制层,表示软件大方向的执行流程以及哪个视图对象将数据展示给用户

1.1.2 MVC的优点

MVC开发方式将不用功能的组件进行隔离,进行分层,有利于代码的后期维护。

1.2 软件框架

软件框架就是软件功能的半成品。框架提供了针对某一个领域所写代码的基本模型,对大多数通用性的功能进行封装。

Spring5MVC框架是现在主流的JavaWeb服务端MVC分层框架,它在功能代码执行效率上进行了优化和增强。

二、搭建Mavenspring项目

2.1 项目基本环境的搭建与运行

2.1.1 项目基本环境搭建步骤

  1. 创建maven-webapp项目。
  2. 在pom.xml中 新增依赖(如下)。

与name、url等同级:

  <parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.5.3</version>
  </parent>

dependencies中新增节点:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>2.3.4.RELEASE</version>
</dependency>
  1. 右键main,new->directory,选择java与resources,新建两个目录。

  2. 创建controller层的TestController与Spring启动类Application,项目结构如图所示。

    在这里插入图片描述

  3. TestController代码

package com.wqq.www.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {
    @RequestMapping("test1")
    @ResponseBody
    public String test1(){
        System.out.println("public String test1()");
        return "test1返回值";
    }
}

注意:

  • @Controller注解注明该类作用于Controller层。
  • @RequestMapping(“test1”),注明匹配方式,即通过根路径+test1进行访问此controller。
  • ResponseBody注明返回体。(此案例可以不使用它)
  1. Application代码
package com.wqq.www;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.1.2 项目运行

1、通过idea编译器Application启动类运行

点击如下所示的按钮,等待加载完成便可运行。

在这里插入图片描述输入网址http:/localhost:8080/test1即可出现如下网页,运行成功。

在这里插入图片描述

2.1.3 打包运行

1、介绍

将SpringBoot Web项目打包成可自动运行的war/jar,直接运行war/jar就可以启动Web项目。war/jar以及内嵌了tomcat,实际项目发布时,只需要这种war/jar包便可以完成项目的发布

2、新增plugins节点

将以下代码放到build标签中(注:不是pluginManagement里面,而是与它同级。)

<plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
</plugins>

3、运行cmd命令

  1. 打开cmd并进入项目根目录。
  2. 输入命令mvn package
  3. 控制台显示BUILD SUCCESS字样,然后刷新项目目录,便可见到war包文件
  4. 若想生成jar包文件只需将pom.xml中的配置更改即可(与groupId、artifactId等节点同级)。其他打包步骤均相同。
<packaging>jar</packaging>
  1. 输入以下命令启动服务器
    java -jar war包的名字.war(没写错)或java -jar jar包的名字.jar

2.2 创建css-JavaScript-HTML-JSP资源

2.2.1 项目结构

在这里插入图片描述

2.2.2 代码

mycss.css:

.myStyle{
    color: red;
    font-size: large;
}

myjs.js:

setTimeout(function (){
    alert("auto run!");
},3000)

test1.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <Meta charset="UTF-8">
        <title>Title</title>
        <script src="js/myjs.js"></script>
        <link rel="stylesheet" type="text/css" href="css/mycss.css">

    </head>
    <body>
        <p>这是html</p><br>
        <h1 class="myStyle">引入css样式</h1>
    </body>
</html>

test2.jsp

<%@ page contentType="text/html; UTF-8" language="java" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="css/mycss.css">
    </head>
<body>
<h2>Hello jsp文件</h2>
    <br/>
    <h1 class="myStyle">引入样式表</h1>
    <c:forEach var="item" items="${mylist}">
        ${item}<br/>
    </c:forEach>
</body>
</html>

TestController(jsp页面通过转发获得myList):

package com.wqq.www.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.servletexception;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

@Controller
public class TestController {
    @RequestMapping("/")
    public String test1(){
        System.out.println("public String test1()");
        return "test1.html";
    }

    @RequestMapping("test1")
    public String test2(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {

        System.out.println("public String test2()");
        ArrayList<String> list = new ArrayList<>();
        list.add("你好 1");
        list.add("你好 2");
        list.add("你好 3");
        request.setAttribute("mylist", list);
        request.getRequestdispatcher("test2.jsp").forward(request,response);
        return "test2.jsp";
    }
}

在地址栏输入http://localhost:8080/test1即可调用controller进入jsp。
在地址栏输入http://localhost:8080/即可调用controller进入test1.html。

三、参数传递

3.1 控制层参数传递

3.1.1 控制层无传参

@RequestMapping(“x1”)
public String x1(){
System.out.println(“public String x1()”);
return “x1.html”;
}

3.1.2 控制层有传参

@RequestMapping("x2")
public String x2(@RequestParam("username") String username, HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
    System.out.println("public String x2()" + username);
    ArrayList<String> list = new ArrayList<>();
    list.add("你好 1");
    list.add("你好 2");
    list.add("你好 3");
    request.setAttribute("mylist", list);
    request.getRequestdispatcher("test2.jsp").forward(request,response);
    return "x2.jsp";
}

3.1.3 控制层有传参简化版

@RequestMapping("x3")
public String x3(String username, String password,HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
    System.out.println("username = " + username + "password = " + password);
    return "x3.jsp";
}

3.1.4 将url参数封装到实体类

创建实体类dto.Userinfo

package com.wqq.www.dto;

public class Userinfo {
    private String username;
    private String password;

    public Userinfo(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public Userinfo() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getpassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

controller层获得实体类参数

 @RequestMapping("login2")
    public String login2(Userinfo userinfo){
        if (userinfo.getUsername().equals("a")&&userinfo.getpassword().equals("aa")){
            return "ok.jsp";

        }
        else {
            return "no.jsp";
        }
    }

3.1.5 限制提交method的方式

注解上加入method = RequestMethod.XXX

@RequestMapping(value = "login3",method = RequestMethod.POST)

3.2 参数类型

3.2.1 控制层方法的参数类型

控制层方法参数类型解释
WebRequest/NativeWebRequest可以访问request的parameters,request 和 session的 attributes,而不需要使用Servlet API。
javax.servlet.ServletRequest / javax.servlet.ServletResponse / MultipartRequest / MultipartHttpServletRequest使用指定的request或response对象。
javax.servlet.http.HttpSession使用指定的HttpSession对象。 注意:访问HttpSession不是线程安全的,如果有多个请求同时访问HttpSession对象,则需要将RequestMappingHandlerAdapter类的synchronizeOnSession属性设置为true.
HttpMethodrequest请求的method方式。
java.util.Locale当前请求的区域。
java.util.TimeZone +java.time .ZoneId当前请求关联的Zone.
java.io.Inputstream java.io.Reader访问request body最原始的数据。
java.io.outputStream java.io.writer访问response body最原始的数据。
@PathVariable访问URI模板变量。
@MatrixVariable访问以name-value形式存在于URI路径中的片段。
@RequestParam访问request中的parameters,该注解是可选的。
@RequestHeader访问request headers中的数据。
@CookieValue访问Cookie。
@RequestBody访问request body。
@httpentity< B>访问request中的headers和body。
@RequestPart处理"multipart/form-data"请求中的part。
java.util.Map org.springframework.ui.Model org.springframework.ui.ModelMap用于View层的交互。
RedirectAttributes重定向添加attributes处理,有2种用法:(1)可以将数据放在query string中。 (2)结合flash attributes将数据存储到临时的空间,当重定向结束后删除临时空间中的数据。
@modelattribute访问已存在的attribute
Errors / BindingResult访问的Errors来自于数据验证和绑定,或者Errors来自于对@RequestBody或@RequestPart的验证。一个Errors或BindingResult参数要声明在验证方法参数之后。
类级别的@SessionAttributes定义HttpSession中的 attributes,在处理完成后触发清理。
@SessionAttribute访问session中的attribute。与作为类级的@SessionAttribute结果而存储在绘画中的Model属性形成对比
@RequestAttribute访问request中的attributes

3.2.2 控制层方法的返回值类型

控制层方法的返回值类型解释
@ResponseBody通过HttpMessageConverters转换返回值,并写入到response中。
httpentity< B> / ResponseEntity< B>Response包括完整的headers和body,并且通过HttpMessageConverters转换返回值,并且谢图到response中
HttpHeaders返回response headers,但不包括body
String使用ViewResolver解析视图的名称
View返回View实例
java.util.Map / org.springframework.ui.Mode添加到隐式Model中的属性,并通过RequestToViewNameT确定视图名称
@modelattribute添加到隐式Model中的属性,并通过RequestToViewNameT确定视图名称
ModelAndView用于确定View和attributes
void如果具有void返回值或返回null值的方法还具有ServletResponse,OutputStream参数或@Response Status注解,则视为已完全处理响应。

3.3 取得request-response-session对象

介绍

通过Controller层的参数HttpServletRequest , HttpServletResponse HttpSession来获取request、response、session对象。

代码

控制层代码

    @RequestMapping("y1")
    public String y1(HttpServletRequest request, HttpServletResponse response, HttpSession session){
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
        System.out.println(request.getServletContext().getRealPath("/"));
        request.setAttribute("my", "requestValue");
        session.setAttribute("my", "sessionValue");
        return "y1.jsp";
}

view层代码(通过requestScope、sessionScope获取不同范围的值):

    request:${my}
    request:${requestScope.my}
    session:${sessionScope.my}

3.4 实现登录失败后的提示信息

介绍

控制层在处理前进行验证,如果所传数据不符合规范,则传到map类型的容器中,前端通过el表达式显示失败信息。

代码

jsp页面代码

<form action="login4" method="post">
    username:<input type="text" name="username"><br/>
    ${message.usernameisnull}<br/>
    password:<input type="text" name="password"><br/>
    ${message.passwordisnull}<br/>
    <input type="submit" value="登录">
</form>

controller层代码

  private Map validateForm4(Userinfo userinfo ){
      Map map = new HashMap();
      if (userinfo.getUsername()  == null||"".equals(userinfo.getUsername()))
          map.put("usernameisnull", "账号为空!");
      if (userinfo.getpassword()  == null||"".equals(userinfo.getpassword()))
          map.put("passwordisnull", "密码为空!");
      return map;
  }

  @RequestMapping("login4")
  public String login4(Userinfo userinfo, HttpServletRequest request){
      Map map =  validateForm4(userinfo);
      if (map.size() > 0) {
          request.setAttribute("message", map);
          return "login4.jsp";
      }
      else {
          if (userinfo.getUsername().equals("a")&&userinfo.getpassword().equals("aa"))
              return "ok.jsp";
          else
              return "no.jsp";
      }
  }

3.5 控制层的重定向

3.5.1 重定向-无参数传递

(1)通过返回"redirect:/xx"来重定向
    @RequestMapping("z2")
    public String z2(){
        System.out.println("z2");
        return "redirect:/z3";
    }
(2)通过返回"xx.jsp"来重定向
    @RequestMapping("z3")
    public String z3(){
        System.out.println("z3");
        return "no.jsp";
    }

3.5.2 重定向-有参数传递

(1)通过返回字符串传递参数
//发送
@RequestMapping("z4")
public String z4() throws UnsupportedEncodingException {
    System.out.println("z4");
    String username = "中国";
    username = URLEncoder.encode(username, "utf-8");
    System.out.println(username);
    return "redirect:/z5?username="+username;
}
//接收
@RequestMapping("z5")
public String z5(String username) throws UnsupportedEncodingException {
    System.out.println("z5");
    username = URLDecoder.decode(username, "utf-8");
    System.out.println("z5 username = " + username);
    return "no.jsp";
}
(2)通过RedirectAttributes.addAttrubute方法传递参数
@RequestMapping("z6")
public String z6(RedirectAttributes attr) throws UnsupportedEncodingException {
    System.out.println("z6");
    String username = "中国";
    String password = "123";
    username = URLEncoder.encode(username, "utf-8");
    attr.addAttribute("username",username);
    attr.addAttribute("password",password);
    return "redirect:/z7";
}
@RequestMapping("z7")
public String z7(String username,String password) throws UnsupportedEncodingException {
    username = URLDecoder.decode(username, "utf-8");
    System.out.println("z7 username = " + username + "password = "+password);
    return "no.jsp";
}
(3)通过RedirectAttributes.addFlashAttrubute方法传递参数

注:该种方式与上面方式的区别,此种方式将参数放入HttpSession中,而上种方式存放于url中。这种方式更安全,更透明。且在重定向结束后,HttpSession自动清除数据,进一步增强安全性。

    @RequestMapping("z8")
    public String z8(RedirectAttributes attr) throws UnsupportedEncodingException {
        System.out.println("z8");
        String username = "中国";
        String password = "123";
        username = URLEncoder.encode(username, "utf-8");
        attr.addFlashAttribute("username",username);
        attr.addFlashAttribute("password",password);
        return "redirect:/z9";
    }
//注意@modelattribute("username")需要加
    @RequestMapping("z9")
    public String z9(@modelattribute("username") String username,@modelattribute("password") String password) throws UnsupportedEncodingException {
        username = URLDecoder.decode(username, "utf-8");
        System.out.println("z9 username = " + username + "password = "+password);
        return "no.jsp";
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐