SpringMVCDemo_v11

1 Spring MVC一些概念

2 SpringMVC 入门(项目)

步骤

是固定的.

image-20191003132325096

image-20191003132912188

解决 maven 加载慢问题

archetypeCatalog
internal 添加一个键值对

image-20191003133015977

image-20191003133324910

创建完是缺少 java,和 resources 两个目录的,自己创建并右键,java 设置为 Sources Root 目录, resources 设为Resources Root 目录.

pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.yydcyy</groupId>
  <artifactId>SpringMVC_v1.1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SpringMVC_v1.1 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>SpringMVC_v1.1</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

resources 目录下新建 xml 配置文件 (复制我这个,全!)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">


</beans>

image-20191003134743763

环境部署完毕,长这样.

配置 Tomcat (不明白的位置,百度关键字搜得到)

image-20191003135614978

添加 tomcat 并将当前项目添加进去. OK

image-20191003141228776

删了这个 index.jsp. 新建 (默认的不带处理 utf8 编码, 中文会出现乱码)

步骤:

web.xml - > spring…xml -> success.jsp -> 视图解析器 -> 测试 Demo

web.xml
java.class
@Controller
public class HelloController {

    @RequestMapping(path="/hello")
        public String sayHello(){
            System.out.println("Hello StringMVC");
            return "sayHello ok";
        }
}
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="cn.yydcyy"></context:component-scan>

    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>


</beans>

执行步骤示意图:

执行步骤

image-20191003150321798

基于组件开发. 适配器是个好东西.

tomcat 默认启动打开 index.jsp 路径若不正确,可以更改配置

image-20191003151725435

image-20191004141024775

记住是选 Artifact (达成 war 包发布)

run 测试即可

image-20191004141146248

RequestMapping注解

@RequestMapping(value=“xxx”) @RequestMapping(path=“xxxx”) 是一样的. 而 value 可以省略,故

@RequestMapping("") 也是对的.

@Controller
@RequestMapping(path="/user")
public class HelloController {

    @RequestMapping(path="/hello")
        public String sayHello(){
            System.out.println("Hello StringMVC");
            return "success";
        }
}

添加 @RequestMapping() 注解后默认目录变成/hello 了, 比如需要访问 hello,应该跳转 /user/hello

image-20191003152437705

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    你好啊, 羽扬
    <a href="user/hello">入门配置成功</a>
</body>
</html>

image-20191003152836611

正确了吧!

image-20191003155327659

不知道为啥,这个都是 404 (应该是 400, 提示我传参数呐)

[params 和 headers 属性用得比较少]]

image-20191004141456400

[ 试了下之前项目(目录层级好像被我玩坏了), 还是打不开.放弃了, 继续 ]

3 请求参数绑定

请求参数绑定入门

domain account bean (setter() getter() toString() )))) - > param.jsp 表单 (往类里封装). bean 属性与 表单 name相同)

User.java -> 引用类型 封装 : user.uname

image-20191004145910047

domain (User , Account)
		private String username;
    private String password;
    private Double money;
    private User user;
....setter() getter() toString()
  
  	private String uname;
    private Integer age;
param.jsp
<br/><H3>把数据封装Account类中</H3>
    <form action="param/saveAccount" method="post">
        姓名:<input type="text" name="username" /><br/>
        密码:<input type="text" name="password" /><br/>
        金额:<input type="text" name="money" /><br/>
        用户姓名:<input type="text" name="user.uname" /><br/>
        用户年龄:<input type="text" name="user.age" /><br/>
        <input type="submit" value="提交" />
    </form>
ParamController.java
@RequestMapping(value = "/saveAccount")
    public String saveAccount(Account account){
        System.out.println("执行了...");
        System.out.println(account);
        return "success";
    }

image-20191004150423747

输出结果:
org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/Users/yuyang/Downloads/Surrounddings/apache-tomcat-8.5.45/webapps/manager] has finished in [24] ms
执行了...
Account{username='yy', password='1231a', money=100.0}User{uname='yy', age=19}
解决 POST 请求 中文乱码问题

(GET 请求没有乱码问题)

使用 Spring 提供的过滤器, 在 web.xml 中添加 :

  <!--配置解决中文乱码的过滤器-->
  <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>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

修改步骤 : param.jsp -> domain ( Account.java ) -> paramController.java -> 运行

请求参数绑定集合类型(List, Map 等)

param.jsp
<%--把数据封装Account类中,类中存在list和map的集合 --%>
    <br/><H3> <form action="param/saveAccount" method="post">
        姓名:<input type="text" name="username" /><br/>
        密码:<input type="text" name="password" /><br/>
        金额:<input type="text" name="money" /><br/>

        用户姓名:<input type="text" name="list[0].uname" /><br/>
        用户年龄:<input type="text" name="list[0].age" /><br/>

        用户姓名:<input type="text" name="map['one'].uname" /><br/>
        用户年龄:<input type="text" name="map['one'].age" /><br/>
        <input type="submit" value="提交" />
    </form>
domain ( Account.java )
    private String username;
    private String password;
    private Double money;

    //private User user;
    private List<User> list;
    private Map<String,User> map;
... //注释掉 User类及其 setter() getter() 修改 toString()
paramController.java
    @RequestMapping(value = "/saveAccount")
    public String saveAccount(Account account){
        System.out.println("执行了...");
        System.out.println(account);
        return "success";
    }
运行

image-20191004152725176

image-20191004152736810

自定义类型转换器

converter 类型转换总接口.

步骤 :

User 类添加 date 属性 -> param.jsp 表单增加 date 属性 -> ParamController.java 添加 saveUser 方法. -> 结果测试.

问题:表格中日期格式固定, 若不符合报错"HTTP Status 400 – Bad Request " 实现后固定格式是yyyy-MM-dd

解决方法 : 写类 implement Converter - > 配置 springmvc.xml 配置开启自转换.

User 类添加 date 属性
private String uname;

    private Integer age;
    private Date date;
... setter() getter() toString ...
param.jsp 表单增加 date 属性
 <br/><H3>自定义类型转换器</H3>
    <form action="param/saveUser" method="post">
        用户姓名:<input type="text" name="uname" /><br/>
        用户年龄:<input type="text" name="age" /><br/>
        用户生日:<input type="text" name="date" /><br/>
        <input type="submit" value="提交" />
    </form>
ParamController.java 添加 saveUser 方法
 /**
     * 自定义类型转换器
     * @param user
     * @return
     */
    @RequestMapping("/saveUser")
    public String saveUser(User user){
        System.out.println("执行了...");
        System.out.println(user);
        return "success";
    }
实现 Converter 类
package com.yydcyy.utils;
import org.springframework.core.convert.converter.Converter;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 把字符串转换日期
 */
public class StringToDateConverter implements Converter<String,Date>{

    /**
     * String source    传入进来字符串
     * @param source
     * @return
     */
    public Date convert(String source) {
        // 判断
        if(source == null){
            throw new RuntimeException("请您传入数据");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        try {
            // 把字符串转换日期
            return df.parse(source);
        } catch (Exception e) {
            throw new RuntimeException("数据类型转换出现错误");
        }
    }
}

image-20191004170930456

千奇百怪的错误

image-20191004180313304

复制一遍就好了. 网上说空格, 字符集(gbk , utf-8 原因啥的)

结果测试:

image-20191004181113702

image-20191004181125030

获取原生 Servlet 的 API

步骤 :

param.jsp -> ParamController.java -> 运行

param.jsp
    <br/><H3>Servlet原生的API</H3>
    <a href="param/testServlet">Servlet原生的API</a>

ParamController.java
 /**
     * 原生的API
     * @return
     */
    @RequestMapping("/testServlet")
    public String testServlet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("执行了...");
        System.out.println(request);

        HttpSession session = request.getSession();
        System.out.println(session); //打印 Session ,证明获取了 session. 可以随便用

        ServletContext servletContext = session.getServletContext(); //作用域最大
        System.out.println(servletContext);

        System.out.println(response);
        return "success";
    }
运行

image-20191004182707821

image-20191004182748093

image-20191004182821678

3 常用注解

1 RequestParam 注解

步骤

anno.jsp ->( com.yydcyy.controller ) AnnoController.java

anno.jsp
<a href="anno/testRequestParam?name=哈哈">RequestParam</a>

AnnoController.java
@Controller
@RequestMapping(value="anno")
public class AnnoController {

    @RequestMapping("/testRequestParam")
    public String testRequestParam(@RequestParam(name="name") String username){
        System.out.println("执行了...");
        System.out.println(username);
        return "success";
    }
}

@Controller 注解别忘了, 否则 404 (注解配置,页面找不到目录)

@RequestParam 作用 : 之前学过, jsp 中?后的参数"name"必须和testRequestParam方法参数 String name 命名一样, 不一样就出错. 通过起别名, 解决这个名字不一样问题

image-20191004191159985

2 RequestBody 注解

GET 方式提交的Body 方法体. (POST 方法没有方法体)

Demo步骤 :

anno.jsp -> AnnoController.java

anno.jsp
        <br/><h3>@RequestBody Demo</h3>
        <form action="anno/testRequestBody" method="post">
            用户姓名:<input type="text" name="username" /><br/>
            用户年龄:<input type="text" name="age" /><br/>
            <input type="submit" value="提交" />
        </form>
AnnoController.java
 /**
     * 获取到请求体的内容
     * @return
     */
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println("执行了...");
        System.out.println(body);
        return "success";
    }
结果 :

image-20191004192017363

image-20191004192029196

这是目前最好的存储方式,转为%E5%存储中文

3 PathVariable 注解

Demo步骤 :

anno.jsp -> AnnoController.java

anno.jsp
    <a href="anno/testPathVariable/10">testPathVariable</a>
AnnoController.java
 /**
     * PathVariable注解
     * @return
     */
    @RequestMapping(value="/testPathVariable/{sid}")
    public String testPathVariable(@PathVariable(name="sid") String id){
        System.out.println("执行了...");
        System.out.println(id);
        return "success";
    }

这个 sid 相当于占位符.

结果 :
image-20191004193321677

image-20191004193337905

这里有个注解传参 restful 风格. (风格就是用了好, 不用没强制性)

4 HiddentHttpMethodFilter过滤器

image-20191004194135087

通过过滤器,模拟提交方式, put / get / …

WebClient 使用静态方法发送请求, 模拟各种请求方式. 见文档说明

5 RequestHeader注解Demo

步骤 anno.jsp -> AnnoController.java 增加对应内容

		<br/><h3>@RequestHeader Demo</h3>
    <a href="anno/testRequestHeader">RequestHeader</a>
 /**
     * 获取请求头的值
     * @param header
     * @return
     */
    @RequestMapping(value="/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value="Accept") String header) throws IOException {
        System.out.println("执行了...");
        System.out.println(header);
        return "success";
    }

结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-efVeohbq-1570196845209)(https://tva1.sinaimg.cn/large/006y8mN6ly1g7mi6b65oej30r00osach.jpg)]

image-20191004194723470

6 CookieValue注解

B - S 对应 cookie (JSECOOKIE) - Session

步骤 :

anno.jsp -> AnnoController.java 增加对应内容

<br/><h3> CookieValue注解 Demo</h3>
    <a href="anno/testCookieValue">CookieValue</a>
/**
     * 获取Cookie的值
     * @return
     */
    @RequestMapping(value="/testCookieValue")
    public String testCookieValue(@CookieValue(value="JSESSIONID") String cookieValue){
        System.out.println("执行了...");
        System.out.println(cookieValue);
        return "success";
    }
结果 Demo

image-20191004195413529

image-20191004195430862

7 ModelAttribute注解

数据不完整时, 优先执行(从库中查数据补全.) 两种实现方式 ①通过 return 返回值方式. ② 通过存储 Map 中, 然后取出

①步骤 :

anno.jsp -> AnnoController.java 增加对应内容

<br/><h3> ModelAttribute Demo</h3>
    <form action="anno/testModelAttribute" method="post">
        用户姓名:<input type="text" name="uname" /><br/>
        用户年龄:<input type="text" name="age" /><br/>
        <input type="submit" value="提交" />
    </form>
 /**
     * ModelAttribute注解
     * @return
     */
    @RequestMapping(value="/testModelAttribute")
    public String testModelAttribute( User user){
        System.out.println("testModelAttribute执行了...");
        System.out.println(user);
        return "success";
    }

    @ModelAttribute
    public User showUser(String uname,Integer age){
        System.out.println("showUser执行了...");
        // 通过用户查询数据库(模拟)
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setDate(new Date());
        return user;
    }

image-20191004203409678

结果 Demo

image-20191004203424516

image-20191004203459840

②无返回值 , 存 Map 方式步骤 :

anno.jsp -> AnnoController.java 增加对应内容

同上
 /**
     * ModelAttribute注解
     * @return
     */
    @RequestMapping(value="/testModelAttribute")
    public String testModelAttribute(@ModelAttribute("我是token") User user){
        System.out.println("testModelAttribute执行了...");
        System.out.println(user);
        return "success";
    }
    @ModelAttribute
    public void showUser(String uname, Map<String, User> map){
        //Map<别名 String, 对象 User>
        System.out.println("showUser执行了...return void, 存入 Map 方式");
        // 通过用户查询数据库(模拟)
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setDate(new Date());
        map.put("我是token",user);
    }


结果 Demo

image-20191004204345216

image-20191004204326652

image-20191004204603076

sout 输出说明执行方法没错. 但设的 age=20 没用? 自动只注如 null 数据?奇怪, 一会补充说明

8 SessionAttributes注解

通过 interface Model 降低获取Request 的耦合

步骤
anno.jsp -> AnnoController.java 增加对应内容结果Demo
<br/><h3>testSessionAttributes</h3>
    <a href="anno/testSessionAttributes">testSessionAttributes</a>

    <br/><h3>getSessionAttributes</h3>
    <a href="anno/getSessionAttributes">getSessionAttributes</a>

    <br/><h3>delSessionAttributes</h3>
    <a href="anno/delSessionAttributes">delSessionAttributes</a>
 /**
     * SessionAttributes的注解
     * @return
     */
    @RequestMapping(value="/testSessionAttributes")
    public String testSessionAttributes(Model model){
        System.out.println("testSessionAttributes...");
        // 底层会存储到request域对象中
        model.addAttribute("msgFlag","狭路相逢勇者胜");
        return "success";
    }

    /**
     * 获取值
     * @param modelMap
     * @return
     */
    @RequestMapping(value="/getSessionAttributes")
    public String getSessionAttributes(ModelMap modelMap){
        System.out.println("getSessionAttributes...");
        String msg = (String) modelMap.get("msgFlag");
        System.out.println(msg);
        return "success";
    }

    /**
     * 清除
     * @param status
     * @return
     */
    @RequestMapping(value="/delSessionAttributes")
    public String delSessionAttributes(SessionStatus status){
        System.out.println("delSessionAttributes...");
        status.setComplete();
        return "success";
    }

三个方法 分别对应1 set Attribute /2 获取 / 3 删除

image-20191004210259616

结果 Demo

点击步骤 : 1 -> 2 (返回) ->3(返回) -> 2

1

image-20191004212442680

-> 2 (返回)

image-20191004212534665

->3(返回)

delete 后更不用说了, 肯定没有.

-> 2

哪里出问题了呐. ===> 少了注解!

image-20191004212655081

@Controller
@RequestMapping(value="anno")
@SessionAttributes(value={"msgFlag"})   // 把 msgFlag 存入到session域对中
public class AnnoController {

重启 Tomcat , 再来

image-20191004212802642

image-20191004212826973

出来了

image-20191004212912564

ok, 又学了一个存 RequestScope 方法. 是不是很酷. 大家加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值