Spring MVC. Пример авторизации в системе.

Download Report

Transcript Spring MVC. Пример авторизации в системе.

Тема 10
XP
eXtreme Programming
1.
2.
3.
4.
5.
6.
7.
Контроллеры (SimpleFormController, UrlFilenameViewController);
Модель и представление соединяются посредством класса
org.springframework.web.servlet.ModelAndView
Для поддержки работы с формой используется командный объект
(JavaBean, который заполняется значениями из полей формы)
Представления реализуются с помощью JSP страниц. Для
упрощения сценариев существуют специальные теги из библиотеки
дескрипторов Spring.
Используются объекты, раскрывающие интерфейс Validator (для
проверки правильности ввода данных в форму)
Перехватчики – классы, которым передается управление перед
(после) тем, как будет выполнен контроллер
Преобразователи представления – класс
InternalResourceViewResolver. Осуществляет преобразование имен
представлений (файл с расширением htm) в фактическое
представление (файл с расширением jsp)
XP
Перенаправление на контроллеры
осуществляет класс
org.springframework.web.servlet.DispatcherServlet
Управление на него передается с помощью
настройки в файле web.xml приложения.
XP
В корневой папке
приложения –
index.jsp
В папке WEB-INF
содержатся файлы
настройки
приложения web.xml
и timex-servlet.xml
Файлы настройки
Hibernate находятся
в папке classes
XP
<target name="copy_files">
<copy todir="${webinf.dir}/${src.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
</copy>
<copy todir="${webinf.dir}/${data.dir}">
<fileset dir="${data.dir}">
<include name="**/*" />
</fileset>
</copy>
</target>
XP
<target name="copy_files">
<copy todir="${webinf.dir}/${src.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
</copy>
<copy todir="${webinf.dir}/${data.dir}">
<fileset dir="${data.dir}">
<include name="**/*" />
</fileset>
</copy>
<copy todir="${war.dir}">
<fileset dir="${web.dir}">
<include name="**/*" />
</fileset>
</copy>
<copy todir="${jsp.dir}">
<fileset dir="${views.dir}" />
</copy>
</target>
XP
<target name="dist" depends="rebuild”>
<mkdir dir="${dist.dir}" />
<war destfile="${war.file}"
webxml="${src.dir}/conf/web.xml">
<fileset dir="${war.dir}">
<include name="**/*.*" />
<exclude name="**/web.xml" />
<exclude name="**/test/*.class" />
<exclude name="**/*mock*.jar" />
</fileset>
</war>
<delete dir="${webinf.dir}/${src.dir}"
failonerror="false" />
</target>
XP
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Time Expression</display-name>
<description>
Example
</description>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
XP
<servlet>
<servlet-name>timex</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>timex</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
XP
Файл контекста приложения задает
JavaBean’ы, используемые в приложении и
их отношения внедрения.
Разберем сначала функциональность
авторизации пользователя.
XP
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!– Настройка URL с расширением htm на контроллер -->
<bean id="urlMap"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<props>
<prop key="/signin.htm">signInController</prop>
<prop key="/signout.htm">signOutController</prop>
<prop key="/ok.htm">urlFilenameController</prop>
</props>
</property>
</bean>
XP
<!-- Bean для перехватчика запросов -->
<bean id="httpRequestInterceptor"
class="com.visualpatterns.timex.controller.HttpReques
tInterceptor">
<property name="signInPage">
<value>signin.htm</value>
</property>
<property name="applicationSecurityManager">
<ref bean="applicationSecurityManager" />
</property>
</bean>
XP
<!--
Bean для контроллера формы ввода логина и пароля -->
<bean name="signInController“
class="com.visualpatterns.timex.controller.SignInController">
<property name="sessionForm"> <value>true</value> </property>
<property name="formView“> <value>/signin</value> </property>
<property name="successView">
<value>redirect:ok.htm</value>
</property>
<property name="commandClass">
<value>com.visualpatterns.timex.controller.SignLogin</value>
</property>
<property name="validator">
<ref bean="signinValidator" />
</property>
<property name="applicationSecurityManager">
<ref bean="applicationSecurityManager" />
</property>
</bean>
XP
<!-- Bean для контроллера выхода из системы -->
<bean name="signOutController"
class="com.visualpatterns.timex.controller.SignOutCon
troller">
<property name="applicationSecurityManager">
<ref bean="applicationSecurityManager" />
</property>
<property name="successView">
<value>redirect:signin.htm</value>
</property>
</bean>
XP
<!-- Bean для валидатора формы ввода пароля -->
<bean id="signinValidator“
class="com.visualpatterns.timex.controller.SignInValidator" />
<!-- Bean для управления параметрами сессии -->
<bean id="applicationSecurityManager"
class="com.visualpatterns.timex.controller.ApplicationSecuri
tyManager"/>
<!-- Bean для перенаправления без контроллера -->
<bean id="urlFilenameController"
class="org.springframework.web.servlet.mvc.UrlFilenameViewCo
ntroller" />
XP
<!-- Bean для определения фактических имен представлений -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResour
ceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</
value>
</property>
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
XP
<!-- Bean для формирования сообщений системы
-->
<bean id="messageSource"
class="org.springframework.context.support.Resourc
eBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
Файл messages.properties должен содержать строки:
Id сообщения = текст сообщения
XP
<!-- Bean для назначения перехватчиков -->
<bean id="urlMapAuthenticate"
class="org.springframework.web.servlet.handler.SimpleUrlHandle
rMapping">
<property name="interceptors">
<list>
<ref bean="httpRequestInterceptor" />
</list>
</property>
<property name="urlMap">
<props> ...
</props>
</property>
</bean>
XP
package com.visualpatterns.timex.controller;
public class SignLogin {
String login, password;
public String getLogin() {return login;}
public void setLogin(String login){this.login=login;}
public String getPassword(){return password;}
public void setPassword(String pass){ password=pass;}
}
XP
package com.visualpatterns.timex.controller;
import javax.servlet.http.HttpServletRequest;
public class ApplicationSecurityManager
{
public static final String USER = "user";
public Object getUser(HttpServletRequest request)
{ return request.getSession(true).getAttribute(USER); }
public void setUser(HttpServletRequest request, Object user)
{ request.getSession(true).setAttribute(USER, user);}
public void removeUser(HttpServletRequest request)
{ request.getSession(true).removeAttribute(USER);}
}
XP
package com.visualpatterns.timex.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.visualpatterns.timex.controller.SignLogin;
import com.visualpatterns.timex.controller.ApplicationSecurityManager;
public class HttpRequestInterceptor extends HandlerInterceptorAdapter
{
private String signInPage;
private ApplicationSecurityManager applicationSecurityManager;
public String getSignInPage()
{ return signInPage;}
public void setSignInPage(String signInPage)
{ this.signInPage = signInPage;}
public ApplicationSecurityManager getApplicationSecurityManager()
{ return applicationSecurityManager;}
public void setApplicationSecurityManager(
ApplicationSecurityManager applicationSecurityManager)
{ this.applicationSecurityManager = applicationSecurityManager;}
XP
public void setApplicationSecurityManager(
ApplicationSecurityManager applicationSecurityManager)
{ this.applicationSecurityManager = applicationSecurityManager;}
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception
{
String log = (String)applicationSecurityManager.getUser(request);
if (log == null)
{
response.sendRedirect(this.signInPage);
return false;
}
return true;
}
}
XP
1. Обращение к форме:
- formBackingObject – создание командного объекта
- initBinder – регистрация редакторов свойств
- showForm
- referenceData – формирование списков
2. Данные в форме некорректные:
- initBinder
- onBind
- onBindAndValidate
- processFormSubmission
- showForm
- referenceData
3. Данные были корректными:
- initBinder
- onBind
- onBindAndValidate
- processFormSubmission
- onSubmit
XP
package com.visualpatterns.timex.controller;
import org.springframework.validation.Errors;
import com.visualpatterns.timex.controller.SignLogin;
public class SignInValidator implements
org.springframework.validation.Validator
{
public boolean supports(Class clazz)
{
return clazz.equals(SignLogin.class); }
public void validate(Object command, Errors errors)
{ SignLogin log = (SignLogin) command;
if (log == null) return;
String login = log.getLogin();
String password = log.getPassword();
if (!(login.equals("admin") && password.equals("admin")))
errors.reject("error.login.invalid");
}
}
XP
package com.visualpatterns.timex.controller;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import com.visualpatterns.timex.controller.ApplicationSecurityManager;
import com.visualpatterns.timex.controller.SignLogin;
public class SignInController extends SimpleFormController
{
private ApplicationSecurityManager applicationSecurityManager;
protected Object formBackingObject(HttpServletRequest request)
throws Exception
{
return new SignLogin();
}
XP
public ModelAndView showForm(
HttpServletRequest request,
HttpServletResponse response,
BindException errors,
Map controlModel) throws Exception
{
if (applicationSecurityManager.getUser(request) != null)
return new ModelAndView(getSuccessView());
return super.showForm(request, response, errors, controlModel);
}
public void onBindAndValidate(
HttpServletRequest request,
Object command,
BindException errors) throws Exception
{
if (errors.hasErrors()) return;
SignLogin formUser = (SignLogin) command;
applicationSecurityManager.setUser(request, formUser.getLogin());
}
XP
public ModelAndView onSubmit(
HttpServletRequest request,
HttpServletResponse response,
Object command,
BindException errors) throws Exception
{ return new ModelAndView(getSuccessView());}
public ApplicationSecurityManager getApplicationSecurityManager()
{
return applicationSecurityManager;
}
public void setApplicationSecurityManager(
ApplicationSecurityManager applicationSecurityManager)
{
this.applicationSecurityManager = applicationSecurityManager;
}
}
XP
package com.visualpatterns.timex.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import com.visualpatterns.timex.controller.ApplicationSecurityManager;
public class SignOutController implements Controller
{
private ApplicationSecurityManager applicationSecurityManager;
private String successView;
public String getSuccessView()
{ return successView; }
public void setSuccessView(String successView)
{ this.successView = successView; }
XP
public ModelAndView handleRequest(
HttpServletRequest request,
HttpServletResponse response) throws Exception
{
applicationSecurityManager.removeUser(request);
return new ModelAndView(getSuccessView());
}
public ApplicationSecurityManager getApplicationSecurityManager()
{ return applicationSecurityManager;}
public void setApplicationSecurityManager(
ApplicationSecurityManager applicationSecurityManager)
{
this.applicationSecurityManager = applicationSecurityManager;
}
}
XP
Цель – перенаправление на страницу авторизации
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:redirect url="signin.htm"/>
XP
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ page contentType="text/html; charset=windows-1251" %>
<html><body><h1>Авторизация</h1>
<form method="post"> <br/>
<spring:bind path="command.*">
<c:if test="${not empty status.errorMessages}">
<c:forEach var="error" items="${status.errorMessages}">
<font color="red"><c:out value="${error}" escapeXml="false" /></font>
<br />
</c:forEach>
</c:if>
</spring:bind>
<c:if test="${not empty message}">
<font color="green"><c:out value="${message}" /></font>
<c:set var="message" value="" scope="session" />
</c:if>
XP
<br/>
Логин: <spring:bind path="command.login">
<input name='<c:out value="${status.expression}"/>'
value='<c:out value="${status.value}"/>' type="text" size="6"
maxlength="6">
</spring:bind>
<br/>
Пароль: <spring:bind path="command.password">
<input name='<c:out value="${status.expression}"/>'
value='<c:out value="${status.value}"/>' type="password"
size="8"
maxlength="10">
</spring:bind>
<br/>
<input type="submit" name="Submit" value="Войти">
</form>
</body>
</html>
XP
<%@ page contentType="text/html; charset=windows-1251" %>
<html>
<body>
<h1>Вы успешно вошли в систему</h1>
<a href="signout.htm">Выйти из системы</a>
</body>
</html>
XP