Spring学习(踩坑记录+日常唠嗑)
害,hi
大学课程j2ee
课程进度总算到了MVC章节,真滴慢呀!,学校就这样,学习还是要靠自己滴
虽然我早已学习过一次,但是还是顶不住有些忘记
这次来做下作业!
(踩坑无数,默默留下眼泪,遇到问题问百度!)
不多说,我要诉说这段故事了?,写这篇记录的时候,我才刚刚完成8篇入党思想汇报(一篇1000字)外加重写入党申请书(1500),泪水滴滴滴
1.实验要求
-
了解Spring MVC中的数据绑定的概念;
-
熟悉Spring MVC中的几种数据绑定类型;
-
掌握Spring MVC数据绑定的使用。
还是看图最直接
是不是很简单,那废话,抄书本代码就能搞定的作业
2.实验步骤
1.创建项目
用eclipise
创建Web项目
用过eclipse
都知道,这软件免费的!,免费的东西除了能白嫖,其他的地方就都凑合
甚至有些蛋疼,曾经几次搞得我深夜疯狂改代码,为了实现一个功能或者效果搞得我头皮发麻
最终发现重启解决了,或者是软件的问题
最后知道真相的我,**眼泪掉下来!**?
希望没用过的小伙伴,可以试试,毕竟改代码这事,多经历下痛苦可以提高心理素质麻,哈哈哈哈哈!
后面再换idea
这个收费的,贵的东西除了贵,其他都好(来自LPL知名解说的话)
当然了,电脑不好就算了吧,因为卡,有点吃内存,不过你配置可以,当我没说,因为用起来比
eclipse
好用到飞起!代码提示实在太符合菜鸟或者懒狗(我)了
虽说eclipse
各种拉跨,但是学校老师还是会教这个软件用于教学的,因为免费,白嫖肯定是香的,写这种课本代码,简直不要太简单,其实eclipse
也能开发大项目的,早些年时候程序员肯定都是用这款,只要你掌握了写代码的基本能力和步骤,有良好的编程习惯,我相信eclipse
你也能用的得心应手!这个软件都能用的飞起的人,现在早是大牛了,哈哈不扯了!
2.导入项目依赖
老师已经准备了这次作业所需要的jar
包
害,题外话:我也不懂,大学上课Maven
也不讲一下,好歹用Maven
创建和管理项目啊,更别提Gradle
这些包管理,项目管理工具如此强大,便捷,方便了我们开发!
套话:使得程序猿只需要注重其中代码实现其中的核心功能
不过确实有些老师脱离行业太久,毕竟公职还是真不错滴!不过还是有老师会关注IT
行业的动态,关注新技术
简而言之就是:IT行业日新月异(操作系统老师说的的?),你们要多关注,多学习,技术方面靠自己努力学习了解才行,我不太懂的
害,常常感觉自己话多,下面废话少点
把项目依赖的jar
包放到lib
目录下
然后add Build下
3.项目配置
贴心的老师为我们连配置文件都准备了,爱了爱了
其实学习过JSP
技术的我,知道web.xml
如何生成创建
看图就行,右键项目找到那个生成!eclipise
要有web项目模块
生成后,就自己写代码配置了
<?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
也挺多,后面你就知道了
写下配置,视图解析器,和扫包,以及注解驱动
<?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
文件夹不是公开资源
正常的流程应该是,公开一个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
属性值都是对应实体类的字段名称相一致!
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();
}
}
复制代码
这里我就发现了,eclipse
BUG,因为我装了插件,所以我在类上用@Controller
后,这个类之下所有代码全部没有代码提示了。用@RestController
不会,前面没觉得是插件问题,所以我四处排查,起初以为是设置问题,后面又试了一下重启,问题依旧得不到解决啊,有点小崩溃,后面查Jar
包有没有错无,也无,最终百度告诉了我答案!果然解决问题,要百度下才行,咱们都是站在巨人的肩膀上门看更远的世界的,不过造轮子,和用轮子区别很大滴~
解决方案:把插件某个设置关闭掉,在那种情况下,不要接管就行
参考链接:blog.csdn.net/iteye_10432…
7.运行测试
配置Tomcat服务器,将项目运行起来
first页面下,输入账号5008,密码666,点击提交
结果:后台接收到了值,并打印在页面上
后台方法中是User 对象为参数类型,说明Spring会帮我将对应的属性的值映射到该类型参数上门去,前提是属性名一致!
也可以改成普通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对象,只要记住只能传递属性名的属性值
没找到相应字段的值,就不会赋值上,所以会空!
third页面:
全部打勾,后点击修改
他会提交到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";
}
}
复制代码
<%@ 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>
复制代码
对了,如何在页面上取值,方法这里提供两种(我会的)
- 使用
JSP
内嵌java
代码,使用out.print()
遍历打印到页面上 - 使用EL表达式
${想取出参数的名称}
坑点:
- 使用
JSP
打印,的话取值要使用resquest
对象,request.getAttribute("userList");
,别忘了导包用,
分割import="java.util.*,com.gip.pojo.User"
不然绝对报错! - 使用EL表达式和一些
Jstl
标签支持,需要导Jar
包,自行上网找找
这边文章里面有用注解,创建对应键值对的炫酷方法:blog.csdn.net/weixin_4507…
SpringMVC中ModelAndView,Model,Request域用法:blog.csdn.net/weixin_4013…
3.实验总结
多复习,多学习,这些小问题,小细节都值得被发现。
在以后的日子中,我也要更加重视这些,你看不到的往往全是细节!