Spring-MVC学习(踩坑记录+日常唠嗑)

Spring学习(踩坑记录+日常唠嗑)

害,hi

大学课程j2ee课程进度总算到了MVC章节,真滴慢呀!,学校就这样,学习还是要靠自己滴

虽然我早已学习过一次,但是还是顶不住有些忘记

这次来做下作业!

(踩坑无数,默默留下眼泪,遇到问题问百度!)

不多说,我要诉说这段故事了?,写这篇记录的时候,我才刚刚完成8篇入党思想汇报(一篇1000字)外加重写入党申请书(1500),泪水滴滴滴

1.实验要求

  1. 了解Spring MVC中的数据绑定的概念;

  2. 熟悉Spring MVC中的几种数据绑定类型;

  3. 掌握Spring MVC数据绑定的使用。

还是看图最直接

image-20210514003007237

是不是很简单,那废话,抄书本代码就能搞定的作业

2.实验步骤

1.创建项目

eclipise创建Web项目

image-20210514003521051

用过eclipse都知道,这软件免费的!,免费的东西除了能白嫖,其他的地方就都凑合

甚至有些蛋疼,曾经几次搞得我深夜疯狂改代码,为了实现一个功能或者效果搞得我头皮发麻

最终发现重启解决了,或者是软件的问题

最后知道真相的我,**眼泪掉下来!**?

希望没用过的小伙伴,可以试试,毕竟改代码这事,多经历下痛苦可以提高心理素质麻,哈哈哈哈哈!

后面再换idea这个收费的,贵的东西除了贵,其他都好(来自LPL知名解说的话)

当然了,电脑不好就算了吧,因为卡,有点吃内存,不过你配置可以,当我没说,因为用起来比

eclipse好用到飞起!代码提示实在太符合菜鸟或者懒狗(我)了

虽说eclipse各种拉跨,但是学校老师还是会教这个软件用于教学的,因为免费,白嫖肯定是香的,写这种课本代码,简直不要太简单,其实eclipse也能开发大项目的,早些年时候程序员肯定都是用这款,只要你掌握了写代码的基本能力和步骤,有良好的编程习惯,我相信eclipse你也能用的得心应手!这个软件都能用的飞起的人,现在早是大牛了,哈哈不扯了!

2.导入项目依赖

老师已经准备了这次作业所需要的jar

image-20210514005229532

害,题外话:我也不懂,大学上课Maven也不讲一下,好歹用Maven创建和管理项目啊,更别提Gradle这些包管理,项目管理工具如此强大,便捷,方便了我们开发!

套话:使得程序猿只需要注重其中代码实现其中的核心功能

不过确实有些老师脱离行业太久,毕竟公职还是真不错滴!不过还是有老师会关注IT行业的动态,关注新技术

简而言之就是:IT行业日新月异(操作系统老师说的的?),你们要多关注,多学习,技术方面靠自己努力学习了解才行,我不太懂的

害,常常感觉自己话多,下面废话少点

把项目依赖的jar包放到lib目录下

然后add Build下

3.项目配置

贴心的老师为我们连配置文件都准备了,爱了爱了

image-20210514010132109

其实学习过JSP技术的我,知道web.xml如何生成创建

看图就行,右键项目找到那个生成!eclipise要有web项目模块

image-20210514010310526

生成后,就自己写代码配置了

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--encodingFilter-->
    <!-- 配置utf-8编码过滤器 -->
    <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>


    <!--DispatcherServlet-->
    <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>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
复制代码

DispatcherServlet:Spring有提供的前端控制器类,控制视图跳转啊,请求巴啦啦之类

下面在src目录下创建springmvc的配置吧

因为,我装了Spring插件,刚开始挺爽的,写这种配置文件时候有提示导入命名空间也方便,但是BUG也挺多,后面你就知道了

image-20210514010830546image-20210514011027278

写下配置,视图解析器,和扫包,以及注解驱动

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


    <!-- 配置SpringMVC -->
    <!-- 1.开启SpringMVC注解驱动 -->
    <mvc:annotation-driven />
    <!-- 2.静态资源默认servlet配置-->
    <mvc:default-servlet-handler/>

    <!-- 3.配置jsp 显示ViewResolver视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 4.扫描web相关的bean -->
    <context:component-scan base-package="com.gip.controller" />

</beans>

复制代码

扫包是扫Controller层的,别搞错就行

4.编写实体类

实验就3个实体类(含一个包装类)就行,直接上代码

package com.gip.pojo;

public class User {
	private Integer id;
	private String password;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getPassword() {
		return password;
	}

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

	@Override
	public String toString() {
		return "User [id=" + id + ", password=" + password + "]";
	}

}

复制代码
package com.gip.pojo;

public class Orders {

	private Integer ordersId;
	private User user;

	public Integer getOrdersId() {
		return ordersId;
	}

	public void setOrdersId(Integer ordersId) {
		this.ordersId = ordersId;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	@Override
	public String toString() {
		return "Orders [ordersId=" + ordersId + ", user=" + user + "]";
	}

}

复制代码
package com.gip.pojo;

import java.util.List;

public class UserVO {

	private List<User> users;

	public List<User> getUsers() {
		return users;
	}

	public void setUsers(List<User> user) {
		this.users = user;
	}

	@Override
	public String toString() {
		return "UserVO [user=" + users + "]";
	}

}

复制代码

5.编写页面

因为视图解析配置,视图跳转的路径如何匹配

bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
复制代码

所以在/WEB-INF/下创建jsp目录

然后写对应的页面,公开的页面放在WebContent目录下

因为WEB-INF文件夹不是公开资源

image-20210514011531433

正常的流程应该是,公开一个index页面,然后在Controller内注册跳转到相应的页面的url和方法,然后index界面内有跳转相应页面url的链接,用前端的思想来解释,拿Vue.js来说就是注册相应组件或视图的路由,路由控制页面的跳转也就是不同组件的展示!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>first 页面</h1>
<form action="${pageContext.request.contextPath}/res" method="post">
用户名:<input type="text" name="id">
密  码:<input type="text" name="password">
密码确认:<input type="text" name="password2">
<input type="submit" value="注册">
</form>
<div style="color:red">
<%
	String msg=(String)request.getAttribute("msg");
	if(msg!=null){
		out.print(msg);
	}
%>
</div>

</body>
</html>
复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>second 页面</h1>
<form action="${pageContext.request.contextPath }/find" method="post">
订单编号:<input type="text" name="ordersId">
所属用户:<input type="text" name="user.id">
<input type="submit">
</form>
</body>
</html>
复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>thrid 页面</h1>
<form action="${pageContext.request.contextPath}/thrid" method="post">
<table width="30%" border="1">
<tr>
<td>选择</td>
<td>密码</td>
</tr>
<tr>
<td>
<input name="users[0].id" value="1" type="checkbox"/>
</td>
<td>
<input name="users[0].password" value="123" type="text"/>
</td>
</tr>
<tr>
<td>
<input name="users[1].id" value="2" type="checkbox"/>
</td>
<td>
<input name="users[1].password" value="321" type="text"/>
</td>
</tr>
</table>
<input type="submit" value="修改"/>
</form>
</body>
</html>
复制代码

这三个页面,都含有基础的表单而已!

input标签内:name属性值都是对应实体类的字段名称相一致!

image-20210514155835693image-20210514155852483

image-20210514155919963

6.编写Controller层

在Controller包下创建一个FirstController

package com.gip.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.gip.pojo.Orders;
import com.gip.pojo.User;

@RestController
public class FirstController {
	@PostMapping("/res")
	public String res(User user) {
		return user.toString();
	}

	@RequestMapping("/find")
	public String find(Orders orders) {
		return orders.toString();
	}
}

复制代码

这里我就发现了,eclipseBUG,因为我装了插件,所以我在类上用@Controller后,这个类之下所有代码全部没有代码提示了。用@RestController不会,前面没觉得是插件问题,所以我四处排查,起初以为是设置问题,后面又试了一下重启,问题依旧得不到解决啊,有点小崩溃,后面查Jar包有没有错无,也无,最终百度告诉了我答案!果然解决问题,要百度下才行,咱们都是站在巨人的肩膀上门看更远的世界的,不过造轮子,和用轮子区别很大滴~

解决方案:把插件某个设置关闭掉,在那种情况下,不要接管就行

参考链接:blog.csdn.net/iteye_10432…

7.运行测试

配置Tomcat服务器,将项目运行起来

image-20210514160022243

first页面下,输入账号5008,密码666,点击提交

image-20210514160130099

结果:后台接收到了值,并打印在页面上

image-20210514160152464

后台方法中是User 对象为参数类型,说明Spring会帮我将对应的属性的值映射到该类型参数上门去,前提是属性名一致!

image-20210514160358746

也可以改成普通Controller,然后使用内置request对象存储数据,然后转发到一个结果页面上去,或者转发回原先页面,jsp页面使用内嵌的语法格式判断逻辑,然后输出相应结果

参考如下:

@RequestMapping("/registerUser")
	public String registerUser(User user, HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Integer id = user.getId();
		String password = user.getPassword();
		String password2 = request.getParameter("password2");
		if (password != null && !password.equals(password2)) {
			String msg = "两次密码不一样!";
			request.setAttribute("msg", msg);
			request.getRequestDispatcher("/first.jsp").forward(request, response);
			System.out.println("两次密码不一样");
		}
		System.out.println("注册成功!GO!");
		request.setAttribute("user", user);
		return "success";
	}
复制代码

second页面请求的是find方法,里面参数类型是Orders,该类里面有属性是User的类型,一对多的关系模式,所以该类是复杂类型,不过没事Spring同样支持,把请求过来的属性值赋值到对应参数的属性里面,不过只能传递引用的类型的属性名.属性名例如:name="user.id"不能直接传递user对象,只要记住只能传递属性名的属性值

image-20210514160806945

image-20210514160736416

没找到相应字段的值,就不会赋值上,所以会空!

image-20210514161519114

third页面:

全部打勾,后点击修改

image-20210514161630075

他会提交到Thrid这个类里面的thrid方法上,该类使用@Controller,参数有UserVO 是个包装类,这样写的目的是想传递**数组或者集合(内含多个对象)**因为必须属性名和前面表单name属性的值一致,所以才需要UserVO 包装类

for (User user : users)遍历出传递过来的UserVO 对象内的属性Users:也就是User类的集合

如果前端打勾了,就会传递id属性,就会执行更改密码操作,

然后将users集合对象,放到内置对象HttpServletRequest里面,使用setAttribute方法创建键值对

提示:使用HttpServletRequest需要导入Tomcat的lib

或者使用Model对象,同样是使用setAttribute方法创建键值对(这也是Spring例子的做法)

Model对象底层也是Request对象实现的,二者都可以使用request.getAttribute得到参数值,或者EL表达式

然后return "ca";前端控制图就会将这些参数,携带转发,跳转到ca页面上

package com.gip.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.gip.pojo.User;
import com.gip.pojo.UserVO;

@Controller
public class Thrid {

	@RequestMapping("/thrid")
	public String thrid(UserVO userList, HttpServletRequest request, Model model) {
		List<User> users = userList.getUsers();
		for (User user : users) {
			if (user.getId() != null) {
				user.setPassword("改123");
			}
		}
		request.setAttribute("userList", users);
		model.addAttribute("userList2", users);
		System.out.println(users);
		return "ca";
	}
}

复制代码

image-20210514161703549

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*,com.gip.pojo.User"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>ca 页面</h1>
<%
if(request.getAttribute("user")!=null){
	out.print(request.getAttribute("user"));
}

if(request.getAttribute("userList")!=null){
	List<User> users = (List<User>)request.getAttribute("userList");
	for (User user : users) {
		out.print(user);
	}
}
%>
<br/>
${userList2}
<br/>
<%
if(request.getAttribute("userList2")!=null){
	List<User> users = (List<User>)request.getAttribute("userList2");
	for (User user : users) {
		out.print(user);
	}
}
%>
</body>
</html>
复制代码

对了,如何在页面上取值,方法这里提供两种(我会的)

  1. 使用JSP内嵌java代码,使用out.print()遍历打印到页面上
  2. 使用EL表达式${想取出参数的名称}

坑点:

  1. 使用JSP打印,的话取值要使用resquest对象,request.getAttribute("userList");,别忘了导包用分割import="java.util.*,com.gip.pojo.User"不然绝对报错!
  2. 使用EL表达式和一些Jstl标签支持,需要导Jar包,自行上网找找

这边文章里面有用注解,创建对应键值对的炫酷方法:blog.csdn.net/weixin_4507…

SpringMVC中ModelAndView,Model,Request域用法:blog.csdn.net/weixin_4013…

3.实验总结

多复习,多学习,这些小问题,小细节都值得被发现。

在以后的日子中,我也要更加重视这些,你看不到的往往全是细节!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享