day55_springmvc

news/2024/11/24 1:58:13/

今日内容

零、 复习昨日

零、 复习昨日

1 maven项目编译后代码在target

2 发现代码都没有错,该写的都有,但是已启动服务器404,查看target,如果编译会后资源不全面,那就删除重新编译

3 重新看一下,如何使用mavne创建javaweb项目

一、参数绑定 【重点】

所谓参数绑定,就是前端发请求中的数据,可以直接在Controller的方法参数中接收.

即前端请求数据和后端方法参数绑定.

1.1 基本类型参数绑定[重点]

基本类型指,常用的几种类型: 基本类型+String+Date

前端页面

<h2>基本类型数据绑定</h2>
<a href="/base.do?id=1&username=张三&score=10.0">请求携带数据-基本类型</a>
<hr>
<form action="/base.do" method="get">id<input type="text" name="id"><br>username<input type="text" name="username"><br>score<input type="text" name="score"><br>birthday<input type="text" name="birthday"><br><input type="submit" value="基本类型">
</form>

后端接收

@Controller
public class DataController {/*** 基本类型自动封装* 要求是: 前端请求的参数名,后端方法的参数名要一致* 【特殊的】 日期,前端发送的日期格式如果是yyyy-MM-dd,springmvc无法默认绑定参数,*            springmvc默认支持yyyy/MM/dd* 两种方案解决:*  1. 前端改,发出的日期格式就是yyyy/MM/dd即可*  2. 后端改,给日期参数加@DateTimeFormat(pattern = "yyyy-MM-dd")*/@RequestMapping("/base")public String base(int id, String username, double score, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){System.out.println("id = " + id);System.out.println("username = " + username);System.out.println("score = " + score);System.out.println("birthday = " + birthday);return "ok";}}

1.2 对象[重点]

场景: 注册/添加/更新

实体类

public class User {private int id;private String username;private String password;private double score;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birthday;// setget
}

前端

<h2>对象数据绑定</h2>
<form action="/obj.do" method="get">id<input type="text" name="id"><br>username<input type="text" name="username"><br>score<input type="text" name="score"><br>birthday<input type="date" name="birthday"><br><input type="submit" value="对象类型">
</form>

后端

    /*** 自动绑定: 要求前端的请求中的参数要和对象的属性名一致*/@RequestMapping("/obj")public String obj(User user){System.out.println("user = " + user);return "ok";}

1.3 数组

场景: 批量删除需要同时接收多个id, (前端是复选框的)

前端

<h2>数组绑定</h2>
<form action="/array.do" method="get"><input type="checkbox" name="ids" value="1">1<input type="checkbox" name="ids" value="2">2<input type="checkbox" name="ids" value="3">3<input type="checkbox" name="ids" value="4">4<input type="submit" value="数组类型">
</form>

后端

    /*** 自动绑定: 要求前端的请求中的参数要和方法参数名(数组名)一致*/@RequestMapping("/array")public String array(int[] ids){System.out.println("ids = " + Arrays.toString(ids));return "ok";}

1.4 List集合

List集合使用场景与数组是一样的

前端

<h2>List绑定</h2>
<form action="/list.do" method="get"><input type="checkbox" name="skill" value="Java">Java<input type="checkbox" name="skill" value="HTML">HTML<input type="checkbox" name="skill" value="Linux">Linux<input type="submit" value="List类型">
</form>

SpringMVC默认是不支持直接封装List的,解决方案

    1. 加注解@RequestParam,就可以【推荐】
    1. 间接的封装List — 创建一个实体类,定义List属性

方案一

@RequestMapping("/list")
public String list(@RequestParam List<String> skill){System.out.println("skill = " + skill);return "ok";
}

方案二

public class User {private int id;private String username;private double score;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birthday;private List<String> skill;  // 定义集合属性// setget    
}
    @RequestMapping("/list")
// 在封装对象数据时,封装listpublic String list(User user){System.out.println("user-skill = " + user.getSkill());return "ok";}

1.5 Map集合

Map是键值对,键和值一一映射.

跟Java对象很类似,属性和属性值一一对应.

所以什么时候需要/可以使用Map来接收参数?

  • 凡是可以用对象接收的都可以使用Map
  • 需要接收两个参数时,可以map

SpringMVC默认不支持直接将参数封装进Map,需要使用@RequestParam

前端

<h2>Map绑定</h2>
<form action="/map.do" method="get">id<input type="text" name="id"><br>username<input type="text" name="username"><br>score<input type="text" name="score"><br>birthday<input type="date" name="birthday"><br><input type="submit" value="Map类型">
</form>
<h2>模糊查询-Map绑定</h2>
<form action="/map.do" method="get">address<input type="text" name="address"><br>floor<input type="text" name="floor"><br>deco<input type="text" name="deco"><br><input type="submit" value="模糊-Map类型">
</form>
name就是map的key
输入框的值就是map的value

后台

    @RequestMapping("/map")public String map(@RequestParam Map<String,Object> map){System.out.println("map = " + map);return "ok";}

1.6 @RequestParam

当封装数据失败时使用该注解,该注解放在参数上

场景一:

前端参数和后端方法参数要一致才能封装数据,当不一致时可以使用@RequestParam来手动指定前端数据封装给参数

image-20230614141904931

场景二:

默认情况下,后端方法的参数列表一旦设置了该参数,就必须传值,不传值就会报错

但是设置@RequestParam(required = false)时就可以不用传值也不报错

image-20230614142411040

场景三:

当后端参数没有传值时,赋值默认值@RequestParam(defaultValue = “666666”)

image-20230614142652370

二、数据乱码

之前自己写过全局编码格式拦截器

现在springmvc提供了编码格式拦截器,直接用即可

    <!-- 编码格式拦截器 --><filter><filter-name>encodingFilter</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>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

三、页面跳转

之前学过的servlet中跳转页面的功能

  • 请求转发:
    • forward
    • req.getDispatcherServlet().forward(req,resp)
    • 请求路径不变
    • 是服务器内部请求
    • 一次请求
    • 请求域的数据可以共享
  • 重定向
    • redirect
    • resp.sendRedirect();
    • 请求路径改变
    • 是浏览器行为
    • 两次请求
    • 请求域的不能共享

请求转发

注意: 默认在使用就是请求转发

在Controller的方法的返回值中写forward:路径即可完成跳转

例如: forward:/view/ok.html forward:/test.do

注意: 跳转后的路径要写完整

 /*** 演示请求转发至其他页面* @return*/@RequestMapping("/forward")public String forward(){System.out.println("执行请求转发" );return "forward:/view/ok.html";}/*** 演示请求转发至其他请求* @return*/@RequestMapping("/forward2")public String forward2(){System.out.println("执行请求转发" );return "forward:/test.do";}

重定向

在Controller的方法的返回值中写redirect:路径即可完成跳转

例如: redirect:/view/ok.html redirect:/test.do

注意: 跳转后的路径要写完整

   /*** 演示重定向至其他页面* @return*/@RequestMapping("/redirect")public String redirect(){System.out.println("执行重定向" );return "redirect:/view/ok.html";}/*** 演示重定向至其他请求* @return*/@RequestMapping("/redirect2")public String redirect2(){System.out.println("执行重定向" );return "redirect:/test.do";}

其他的请求转发和重定向的特点和之前学习的servlet是一样的,复习.

四、数据共享

数据共享是指: 数据域,即

  • request域
    • 只有在一次请求中有效,即请求转发后能取出
  • session域
    • 一次会话有效,只要会话不结束,无论请求转发还是重定向都能取出
package com.qf.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 演示域对象(Request,Session)*/
@Controller
public class ScopeController {@RequestMapping("/req")public String requestAndSession(HttpServletRequest request, HttpSession session) {// 存入request.setAttribute("req","req-Value");session.setAttribute("se","se-Value");return "forward:/req2.do";}@RequestMapping("/req2")public String requestAndSession2(HttpServletRequest request, HttpSession session) {// 取出String v1 = (String) request.getAttribute("req");System.out.println("v1 = " + v1);String v2 = (String) session.getAttribute("se");System.out.println("v2 = " + v2);return "ok";}
}

五、静态资源处理

目前,前端控制器(DispatcherServlet)类映射的是==*.do==,前端的静态资源例如:html,js,css,图片 等都是不影响加载的

但是,如果前端控制器(DispatcherServlet)类映射的是==/==,那就是所有请求都要经过前端控制器,静态资源也不例外. 那么此时静态资源是无法完成映射.

此时就需要静态资源处理!!!

web.xml文件

    <!-- 前端控制器 --><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><!-- 此处要改成 / ,这样才能映射匹配到所有请求 --><url-pattern>/</url-pattern></servlet-mapping>

项目中定义一个css文件夹,定义一个css文件,在index.jsp页面中引入静态资源css,查看效果即可

image-20230613165553909

springmvc.xml文件

    <!-- 静态资源映射mapping="访问路径"location="本地资源位置""/**" 前端的任何请求去匹配后台处于"/"下的静态资源--><mvc:resources mapping="/**" location="/"/>

ps:

<mvc:default-servlet-handler/> 也行

六、拦截器 【重点】

6.1 作用

  • 之前用来做编码格式过滤
  • 登录认证
  • 等等

6.2 定义拦截器

  • 自定义类
  • 实现接口
  • 重写方法
  • springmvc.xml配置
package com.qf.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 拦截器类*/
public class MyInterceptor implements HandlerInterceptor {/*** 目前Controller,执行前,执行拦截* 一般用于: 校验* @return  返回true,即认为放行,返回false不放行*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("前 pre" );// 写项目时,这里通过数据判断,来决定是返回true放行,还是返回false不放行return true;}/*** 在目标Controller方法执行完,但是afterCompletion方法前执行* 对目标方法的返回再处理,可以对响应再定制.*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("post" );}/*** 目标Controller的方法全部执行完执行* 一般: 资源回收*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("after" );}
}

以上方法是按需重写,一般来说用的是前置方法preHandle()

    <!-- 配置拦截器 --><mvc:interceptors><mvc:interceptor><!-- mapping path: 要拦截的路径 --><!-- <mvc:mapping path="/user/**"/>--><mvc:mapping path="/**"/><!-- exclude-mapping 排除拦截的 --><mvc:exclude-mapping path="/login"/><mvc:exclude-mapping path="/test.do"/><!-- 指定拦截器类 --><bean class="com.qf.interceptor.MyInterceptor"/></mvc:interceptor></mvc:interceptors>

七、异常处理

以前处理异常

  • 抛出
  • 视图捕获

全靠自己在每个方法中处理异常

springmvc框架提供了一个全局的异常处理机制,可以处理Controller的所有异常

这种方法,集中管理异常


  • 建类
  • 实现接口
  • 重写方法
  • 配置
@Component // 配置到spring容器
public class MyExceptionHandler implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {ModelAndView mv = new ModelAndView( );if (ex instanceof ArithmeticException) {mv.setViewName("redirect:/view/500.html");} else if (ex instanceof AuthException) {mv.setViewName("redirect:/view/auth.html");}return mv;}
}

测试

后台Controller抛出异常,测试!

任务

重点: 参数绑定- 重复
删除数据发请求-接收
添加/注册/更新  -> 接收
批量删除 --> 接收其中使用的注解要会
------------------------
重新整合spring和mybatis--------------------------------------
思考:
写项目后端数据如何在页面展现?
方案1: 存储域,在jsp页面取值
方案2: 不用jsp,用html开发,后端数据如何给前端展现?

http://www.ppmy.cn/news/436437.html

相关文章

Python算法练习6.17

leetcode 1768 交替合并字符串 给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 输入&#xff1a;word1 &qu…

win10对比度调节

还可以直接在桌面上右键:

Windows 10 专业版高对比度开了之后怎么调回去?

最新win10系统 21H1 19043.928 版本 误点了高对比度 如何还原&#xff0c;坑就坑在旧版本网上各种 1、在桌面右键&#xff0c;在菜单中点击【个性化】&#xff1b; 2、在左侧点击【颜色】&#xff1b;这样去操作就可以成功设置了&#xff1b; 3、再就是下载新主题 等等解决都…

如何在电脑上调整图像的亮度与对比度?多张图片怎么调整?

喜欢摄影的小伙伴都知道&#xff0c;一张照片的展示与摄影师的拍照技术有很大关系。如果拍出来的照片太亮或者太暗&#xff0c;色差大都是不合格的。平时一张生活照可以用手机自带调整功能进行处理了。如果需要对多张图片调整亮度对比度&#xff0c;手机就无法处理了。今天小编…

图片的对比度怎么调整?

首先先来了解一下什么是对比度&#xff08;https://www.yasuotu.com/liangdu&#xff09;&#xff0c;对比度是一张图片上明暗以及色彩的对比强度&#xff0c;并不是说照片的对比度越高越好&#xff0c;对比度是需要根据实际情况而定的&#xff0c;一般来说&#xff0c;风景图片…

gta5怎么设置画质最好_GTA5画面如何设置最好_GTA5画质设置成最高配置推荐-win7之家...

GTA5是侠盗猎车手的简称,这款游戏是很多玩家都很热爱的一款网络游戏,在游戏过程中,我们可以通过画面设置来提高游戏的画面效果,不过还要顾及游戏的流畅性,那么GTA5画面如何设置最好呢?针对这个问题,小编给大家推荐一下GTA5画质设置成最高配置的步骤吧。 GTA5画面设置推荐…

gta5怎么设置画质最好_GTA5画面设置怎样最好?GTA5画面推荐设置

在侠盗猎车手GTA5中玩家可以通过画面设置来提高游戏内画面效果的精细程度,当然我们还要顾及游戏的流畅性,那么怎么样设置才是最好的呢?下面小编给大家带来大神玩家的推荐设置。 GTA5画面设置推荐:以竞速性能为目标 1080P分辨率画面设置参考及原因(仅作推荐!因为每个人的硬…

win10系统高对比度模式的切换

问题描述&#xff1a; 在win10系统登录输入密码界面&#xff0c;发现无系统默认背景而为黑色&#xff0c;当进入到系统后&#xff0c;桌面无背景且为黑色&#xff0c;下方任务栏为黑色且有多个格子&#xff0c;打开资源管理器或系统设置时&#xff0c;背景也为纯黑色&#xff…