SpringMVC02
注意事项
- 包的命名分级,com…的扫描范围包括jar包,cn的扫描范围是对应的包下面。
案例1:制作三个网页reg.jsp、login.jsp、index.jsp
步骤
- 生成web.xml,在web中设置servlet,进行初始化。
- 布置Tomcat运行环境
- 配置pom.xml文件,导入springwebmvc依赖包
- 导入spring的配置文件applicationContext.xml文件,使用组件扫描+注解的方式创建管理对象。
- 对象中设置处理请求的处理方法,使用注解@RequestMapping(“请求路径”)设置请求映射关系。
web.xml
<servlet>
<servlet-name>SpringMVC02</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--classpath为resources文件夹 -->
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!-- 启动就加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC02</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
**applicationContext.xml **
<context:component-scan base-package="cn.spring.controller"/>
<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver"
>
<property name="prefix" value = "/WEB-INF/"></property>
<property name="suffix" value = ".jsp"></property>
</bean>
**创建的对象UserController **
@Controller
public class UserController {
@RequestMapping("reg.do")
public String reg() {
return "reg";
}
@RequestMapping("login.do")
public String login() {
return "login";
}
}
1.接收客户请求
###1.1 使用HttpServletRequest的getParameter(“参数名称与jsp中的名称一致”),得到的值默认为String类型。
@RequestMapping("handle_reg.do")
public String handleReg(HttpServletRequest httpServletRequest) {
String uesername = httpServletRequest.getParameter("username");
String password = httpServletRequest.getParameter("password");
String age = httpServletRequest.getParameter("age");
String phone = httpServletRequest.getParameter("phonenumber");
String email = httpServletRequest.getParameter("email");
System.out.println("username = "+uesername);
System.out.println("password = "+password);
System.out.println("phonenumber = "+phone);
System.out.println("age = "+age);
System.out.println("email = "+email);
return "handle_reg";
}
1.2 直接将要请求的参数声明为处理方法的所对应的类型的参数,适用于参数较少且变动少的情况。
1.3 将所请求的参数封装成一个对象,然后控制器端的处理方法的参数就是该对象实例。
1.4 参数请求可能会发生变化时,使用第三种做法。原因:便于控制器的参数的调整和维护,不需要直接改变处理方法。
2.转发与重定向
2.1 区别:转发时客户发出了1次请求,重定向客户端发出了2次请求。具体表现在浏览器的地址栏的URL式第一次请求的URL,而重定向为第二次地URL。
** 2.2 转发:请求—>服务器端—>处理,在处理数据完成时,需要显示某些数据,控制器时java类,不易于显示;所以出了jsp技术,易于显示数据而不适合完成java代码地书写。转发就是将这两种技术进行综合互补解决问题。(控制器---->jsp显示)。JSP文件一般放在WEB-INF文件夹,不允许客户端直接访问JSP,必须通过控制器访问。**
** 2.3 重定向:当控制器处理完数据时,并且客户端需要访问下一个界面时,可以使用重定向进行响应,具体过程:向客户端响应302(大多情况),给出重定位地目标地址,客户端接收到302响应码时,向目标地址发起请求。**
应用场景
- 客户端地浏览器地URL是否需要发生变化,不变时,刷新时是否需要变化
- 控制器处理完数据时,是否显示相关数据。如是,选择转发。
###2.4 重定向的实现
在控制器中使用String类型作为处理请求的方式的返回类型,并用字符串redirect:重定向的目标路径实现重定向。
2.5 封装转发的数据
2.5.1.使用HttpServletReques封装转发数据
在处理请求的方法中加入HttpServletReques类型参数,转发数据时,调用HttpServletReques对象的getAttribute(String name, Object value)方法封装数据,最终通过return语句转发。
2.5.2 使用ModelAndView进行数据封装
代码实现了判断注册用户名的功能,如果注册的用户名已经存在,则转到erro页面。
@RequestMapping("handle_reg.do")
public ModelAndView handleReg(User user) {
System.out.println(user);
if (user.getUsername().equals("quan")) {
String errormessageString = "您输入的用户名已经存在";
//封装错误信息
Map<String, Object> model = new HashMap<String, Object>();
//数据名称,数据内容
model.put("err_message",errormessageString);
//第一个参数为view名称,第二个参数是封装的数据map
ModelAndView modelAndView = new ModelAndView("erro", model);
return modelAndView;
}else {
//重定向
return new ModelAndView("redirect:login.do");
}
}
erro.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>操作失败</title>
</head>
<body>
<h1>操作失败!</h1>
<!--这里要显示的名称为modelAndView封装的数据名称 -->
<h2>${err_message}</h2>
</body>
</html>
2.5.3 使用ModelMap封装转发的数据
@RequestMapping("handle_reg.do")
public String handleReg(User user,ModelMap map) {
System.out.println(user);
if (user.getUsername().equals("quan")) {
String errormessageString = "您输入的用户名已经存在";
//封装错误信息
map.addAttribute("err_message", errormessageString);
return "erro";
}else {
//重定向
return null;
}
}
小案例:实现判断用户名和密码错误,然后封装错误信息,利用重定向发生跳转。注册错误–>erro,登录时密码或用户名错误—>erro,登录成功—>主页
控制器类
@Controller
public class UserController {
@RequestMapping("reg.do")
public String reg() {
return "reg";
}
@RequestMapping("login.do")
public String login() {
return "login";
}
@RequestMapping("handle_reg.do")
public String handleReg(User user, ModelMap map) {
System.out.println(user);
if (user.getUsername().equals("quan")) {
String errormessageString = "您输入的用户名已经存在";
// 封装错误信息
map.addAttribute("err_message", errormessageString);
return "erro";
} else {
// 重定向
return "redirect:login.do";
}
}
@RequestMapping("handle_login.do")
public String handleLogin(String username, String password, ModelMap map) {
String message;
if ("admin".equals(username)) {
if ("1234".equals(password)) {
return "redirect:index.do";
} else {
message = "密码错误!";
}
} else {
message = "用户名错误!";
}
map.addAttribute("err_message", message);
return "erro";
}
}
注册页面:reg.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户注册</title>
</head>
<body>
<h1>用户注册</h1>
<!-- 数据私密、太长要使用post传输给服务器 -->
<form action="handle_reg.do" method="post">
<p>请输入用户名:</p>
<p>
<input name="username" />
</p>
<p>请输入密码:</p>
<p>
<input name="password" />
</p>
<p>请输入年龄:</p>
<p>
<input name="age" />
</p>
<p>请输入手机号码:</p>
<p>
<input name="phonenumber" />
</p>
<p>请输入电子邮箱:</p>
<p>
<input name="email" />
</p>
<p>
<input type="submit" value="注册" />
</p>
</form>
</body>
</html>
登录页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户登录</title>
</head>
<body>
<h1>用户登录</h1>
<!-- 数据私密、太长要使用post传输给服务器 -->
<form action="handle_login.do" method="post">
<p>请输入用户名:</p>
<p>
<input name="username" />
</p>
<p>请输入密码:</p>
<p>
<input name="password" />
</p>
<p>
<input type="submit" value="登录" />
</p>
</form>
</body>
</html>
主页
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>主页</title>
</head>
<body>
<h1>主页</h1>
</body>
</html>
错误页
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>操作失败</title>
</head>
<body>
<h1>操作失败!</h1>
<h2>${err_message}</h2>
</body>
</html>
Session(牺牲空间换取时间)
**使用Session的原因:**Http协议是无状态协议,前序请求的数据不会保留,后续请求无法直接使用前序请求的数据。Session是应用于服务器端长时间保持数据的技术,将数据保存在服务器的内存中。每个浏览器对应Session是唯一的,用于识别用户身份。
**Session的特点:**一般会保持当前状态,数据的有效时间为15分钟或更长。在此期间,如果客户端始终与服务端交互,则有效期会顺延。反之,到有效期时,数据消失。
应用场景
- 保存用户的唯一标识
- 保存高频率使用的数据,例如多个页面都需要的用户名。
使用Session
使用HttpSession类,使用putvalue(“显示的数据名称”,显示的数据的值)方法封装数据。然后直接在jsp页面根据数据名称获取显示。