Это пример интеграции фреймворков, включающий SpringMVC/MyBatis/Apache Shiro.
- Демонстрационные данные следует импортировать db.sql
- Логин и пароль демонстрационного аккаунта —
12345
![]()
В демонстрационном проекте используется стиль RESTful, а не традиционный стиль с отображением URL по шаблону
*.do
,*.action
.
<!-- Когда DispatcherServlet используется в web.xml с <url-pattern>/</url-pattern>, это позволяет отображать статические ресурсы -->
<mvc:default-servlet-handler />
<!-- Поддерживает отображение статических ресурсов из директории WEB-INF -->
<mvc:resources mapping="/static/**" location="/static/" />
<!-- Spring MVC -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
```#### Создание пользовательских аннотаций и замена **JSON** конвертора
> В файле [spring-mvc.xml](src/main/resources/spring-mvc.xml) выполните следующую конфигурацию
```xml
<!-- Включение аннотаций -->
<mvc:annotation-driven>
<!--
| Регистрация пользовательской аннотации
|
| <mvc:argument-resolvers>
| <bean class="org.springagg.spring.bind.method.CurrentUserMethodArgumentResolver"/>
| </mvc:argument-resolvers>
| -->
<!-- Регистрация конвертора FastJson -->
<mvc:message-converters
register-defaults="true">
<!-- Предотвращает скачивание JSON при выполнении AJAX в IE -->
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<!--
| Здесь можно самостоятельно конфигурировать некоторые вещи, такие как формат времени, вывод null в "", и так далее
| <property name="serializerFeature"></property>
| -->
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
```## Усиление контроллеров
Демонстрационный проект использует `JSON` в качестве возвращаемых данных. Когда пользователь выполняет операцию, для которой нет прав доступа, возникает исключение. Если обработка исключения направляет пользователя на представление, то возвращаются данные, не соответствующие формату `JSON`. Для того чтобы вернуть действительные данные `JSON`, используется аннотация `@ControllerAdvice` для определения обработчика исключений.
> Аннотация `@ControllerAdvice` внутренне использует методы с аннотациями `@ExceptionHandler`, `@InitBinder`, `@ModelAttribute`, которые применяются ко всем методам, отмеченным аннотацией `@RequestMapping`.
1. [DefaultExceptionHandler.java](/src/main/java/org/springagg/web/exception/handler/DefaultExceptionHandler.java) - Обработчик исключений
```java
/**
* Обработчик исключений
*
* @author ArchX[archx@foxmail.com]
*/
@ControllerAdvice
public class DefaultExceptionHandler {
/**
* Исключение "Нет прав доступа"
*
* @param request
* @param e
* @return
*/
@ExceptionHandler({UnauthorizedException.class})
@ResponseBody
public JsonModel processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e) {
JsonModel json = new JsonModel();
json.setSuccess(false);
json.setStatus("exception");
json.setMessage("Нет прав доступа " + e.getMessage());
json.setObj(e.getClass().getName());
return json;
}
}
``````markdown
/**
* Исключение "Операция недопустима"
*
* @param request
* @param e
* @return
*/
@ExceptionHandler({OperationNotAllowedException.class})
@ResponseBody
public JsonModel processOperationNotAllowedException(NativeWebRequest request, OperationNotAllowedException e) {
JsonModel json = new JsonModel();
json.setSuccess(false);
json.setStatus("exception");
json.setMessage("Операция недопустима " + e.getMessage());
json.setObj(e.getClass().getName());
return json;
}
}
}
}
``` 2. Конфигурация файла `spring-mvc.xml` в директории `src/main/resources/spring-mvc.xml`.
```xml
<!-- Сканирование контроллеров с отключенным использованием дефолтных фильтров, чтобы избежать повторного сканирования аннотаций @Service, @Repository и т.д., что может привести к потери транзакций -->
<context:component-scan base-package="org.springagg.web"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
Дополнительные детали конфигурации Spring MVC можно найти в исходном коде.
Плагин пагинации основан на механизме перехватчика MyBatis и реализован до того как SQL-запрос будет подготовлен. В зависимости от используемой базы данных, он создаёт новый запрос пагинации перед тем как выполнить его. Плагин по умолчанию поддерживает пагинацию только для MySQL и Oracle. Конфигурация осуществляется следующим образом:> При использовании чистого MyBatis, конфигурация плагина производится в файле конфигурации MyBatis.
<!-- Конфигурация плагина -->
<plugins>
<plugin interceptor="org.springagg.mybatis.plugins.PaginationInterceptor">
<!-- Конфигурация свойств плагина. Приоритет отдается конфигурации диалекта, если нет совпадений используется реализация класса. Без конфигурации выбрасывается исключение -->
<!-- Диалект базы данных. По умолчанию поддерживаются только MySQL и Oracle -->
<property name="dialectType" value="mysql"/>
<!-- Реализация класса диалекта. Можно использовать свою реализацию -->
<!-- Нужно реализовать интерфейс org.springagg.mybatis.IDialect -->
<property name="dialectClazz" value="org.springagg.mybatis.dialect.MySqlDialect"/>
</plugin>
</plugins>
```> При интеграции с Spring, конфигурация плагина происходит через атрибуты бины `SqlSessionFactoryBean`.
```xml
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="plugins">
<array>
<!--
Конфигурация плагина пагинации
Плагин сначала пытается найти реализацию класса по имени диалекта, если не найдено, то используется пользовательская реализация. Без конфигурации выбрасывается исключение
dialectType - тип диалекта базы данных
Поддерживаются значения: mysql|oracle
dialectClazz - пользовательская реализация класса диалекта
Нужно реализовать интерфейс org.springframeworkagg.mybatis.IDialect
-->
<bean id="paginationInterceptor"
class="org.springframeworkagg.mybatis.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"/>
<property name="dialectClazz"
value="org.springframeworkagg.mybatis.dialect.MySqlDialect"/>
</bean>
</array>
</property>
. . . пропущено . . .
``` </bean>
Плагины используют конфигурацию
dialectType
в приоритетном порядке. Если требуется создание пользовательского плагина пагинации или использование других баз данных, реализуйте интерфейсorg.springframework.mybatis.IDialect
, а затем настройте свойствоdialectClazz
. Способ вызова ИспользуйтеRowBounds
и его подклассы как параметры пагинации для активации плагина пагинации. Дополнительные детали можно найти в исходном коде.
@Repository
public interface StudentMapper {
List<Student> all(RowBounds pagination);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- НАМЕСПЭЙС должен совпадать с путём к интерфейсу -->
<mapper namespace="org.springagg.web.dao.StudentMapper">
<!-- Все студенты -->
<select id="all" resultType="Student">select r.sn recid, r.* from tb_student r</select>
</mapper>
Для более подробной информации о способах использования плагина пагинации обратитесь к http://git.oschina.net/archx/mybatis-pagination
Конфигурация
shiro
следует руководству «Учебник по Shiro» от Тао Го http://jinnianshilongnian.iteye.com/blog/2018398 Ограничение попыток входа пользователями после нескольких неправильных паролей Когда пользователи пытаются войти несколько раз с неверным паролем, им запрещается доступ к аккаунту. Период блокировки указан в конфигурационном файле [ehcache.xml]```xml [src/main/resources/ehcache.xml]
```markdown
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="es">
<diskStore path="java.io.tmpdir"/>
<!-- Кэш попыток входа 10 минут -->
<cache name="passwordRetryCache" maxEntriesLocalHeap="2000"
eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="0"
overflowToDisk="false" statistics="true">
</cache>
...
</ehcache>
[Максимальное количество попыток](src/main/resources/spring-shiro.xml) конфигурация
```markdown
<!-- Кредитный матчингатор расширяет валидатор с ограничением количества попыток -->
<bean id="credentialsMatcher"
class="org.springframework.security.core.userdetails.UserDetailsServiceImpl">
<constructor-arg ref="cacheManager"/>
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="1"/>
<property name="storedCredentialsHexEncoded" value="true"/>
<!-- Максимальное количество попыток по умолчанию 5 -->
<property name="maxCount" value="3"/>
</bean>
Дополнительные детали см. в исходном коде
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )