基本的过程、问题与解决
简单环境配置
jar包
web.xml
在里面配置有前端控制器Dispatcher
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app.xsd"
id="WebApp_ID" version="3.0">
<display-name>chapter14</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<!-- 配置前端控制器======== -->
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 若没有标注init-param,加载时则会自动去web-inf下寻找命名方式为: -->
<!-- servletName-servlet.xml 的配置文件 -->
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<!-- 如果没有这一句,则会在第一个servlet请求时加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
spring-config.xml
扫描的包,注解驱动,视图解析器(前后缀),拦截器配置
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="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.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
<!-- 扫描指定的包========= -->
<context:component-scan base-package="com.ssm.controller"/>
<!-- 配置注解驱动========== -->
<mvc:annotation-driven />
<!-- 定义视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置前缀后缀 -->
<property name="prefix" value="/JSP/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 应用案例的拦截器配置===== -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.ssm.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
控制器、拦截器、数据类型、jsp页面
数据类型——User
User类型:private id、username、password 和set、get、toString方法
控制器类
问题1:条件语句总是判断失误
答案:“&&”才是逻辑运算符,“&”是位运算符!
String的字符串比较不能用 两个等于号,这个比较的是地址。用equals(),还有equalsIgnoreCase()是忽略大小写的比较。
问题2:"redirect:"的问题!返回“redirect:main”的url是,总是会被拦截器拦截
答案:redirect的意思是重定向,可以用于输入url1自动跳转到url2。
后来加了拦截器方法中注释的if条件句去检验才知道,返回“redirect:main”时,会清除session内存,就像是重新打开这个“main”一样,所以才会一直被拦截器拦截。
package com.ssm.controller;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import com.ssm.po.User;
@Controller
public class UserController {
@RequestMapping(value="/toLogin",method=RequestMethod.GET)
public String toLogin() {
return "login";
}
@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(User user,Model model,HttpSession session) {
String username=user.getUsername();
String password=user.getPassword();
if(username!=null&&username.equals("hanke")) {
if(password!=null&&password.equals("123")) {
//setAttribute方法的参数为String和object
//就是传回去一个类,String是name,object是value
session.setAttribute("user_session", user);
System.out.println("跳转前"+username+password);
return "redirect:main";
}
}
model.addAttribute("msg", "用户名或密码错误,请重新输入!");
return "login";
}
@RequestMapping(value="/main")
public String toMain() {
return "main";
}
@RequestMapping(value="/logout")
public String logout(HttpSession session) {
//invalidate()方法是让session失效
session.invalidate();
return "toLogin";
}
}
拦截器
内部只有一个起作用的方法
问题3:继承HandleInterceptor和继承WebRequestInterceptor的区别
答案:三种方法都一样,区别在于参数类型的变化。
问题4:总是无法登陆成功,后来发现的一个原因是session获取失败
答案:我原来写的是:User user=(User) session.getAttribute(“user”);
此处的getSession中的String参数一定要控制器方法中setSession方法中的String参数相同,才能成功从session中提取存储的信息。
改成:User user=(User) session.getAttribute(“user_name”);
问题5:“req.getRequestDispatcher(”/JSP/login.jsp").forward(req, resp);"的用途
答案:没有,谁知道告诉我。
package com.ssm.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.ssm.po.User;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object arg2) throws Exception {
// TODO Auto-generated method stub
String url=req.getRequestURI();
//根据url判断跳转的页面能不能放行
if(url.indexOf("/toLogin")>=0) return true;
if(url.indexOf("/login")>=0) return true;
HttpSession session=req.getSession();
//此处的getAttribute()方法中的参数要和setAttribute()方法中的String参数相一致
User user=(User) session.getAttribute("user_name");
if(user!=null) {
return true;
}
req.setAttribute("msg", "请先登录!");
//用来检验redirect:main问题,如果返回redirect:main则会输出null
/*System.out.println("跳转后");
if(user==null) System.out.println("null");
*/
req.getRequestDispatcher("/JSP/login.jsp").forward(req, resp);
return false;
}
@Override
public void postHandle(HttpServletRequest req, HttpServletResponse resp, Object arg2, ModelAndView arg3)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(HttpServletRequest req, HttpServletResponse resp, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
}
jsp页面
main.jsp
问题6:返回/logout和/toLogin的区别
答案:区别就在于返回/toLogin不会被拦截,会直接通过。返回/logout则会被拦截。表现在前端的区别就是:会不会显示${msg}信息。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>管理主页</title>
</head>
<!--当前信息用EL表达式调用了session中user类的username属性 -->
<body>
当前信息:${user_session.username}
<a href="${pageContext.request.contextPath}/toLogin">退出</a>
<!-- 转到logout还是toLogin的区别在于拦截器那里 -->
<!-- 是走return true还是最底端的false -->
</body>
</html>
login.jsp
问题7:不显示msg的信息
答案:想要显示${msg}首先得写出来,不写出来怎么显示呢。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/login" method="post">
${msg}<br>
登录名:<input type="text" name="username" id="username"/><br>
密 码:<input type="password" name="password" id="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>