日期Date和String之間的轉換:
1. 全局轉換器(推薦使用)
1. 建立類實現Converter接口,實現Convert方法
public class StringToDateConvert implements Converter<String, Date> {
@Override
public Date convert(String resource) {
if(resource == null){
throw new RuntimeException("請輸入值");
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try {
Date parse = df.parse(resource);
return parse;
} catch (ParseException e) {
throw new RuntimeException("數據格式轉換異常");
}
}
}
2. 在SpringMVC的配置文件中進行配置轉換器
<!--配置自定義日期轉換器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.wzlove.utils.StringToDateConvert"/>
</set>
</property>
</bean>
<!--開啓MVC註解驅動(加載處理器映射器和處理器適配器)-->
<mvc:annotation-driven conversion-service="conversionService">
</mvc:annotation-driven>
2. 屬性轉換器
使用註解進行轉換:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
private Date departureTime;
對於日期在頁面的展現(get方法須要注意)
對於日期在頁面上的展現考慮使用字符串,多建立一個String屬性,在前臺展現的時候使用這個字符串屬性,記得轉換類型就好.
實體類:
private Date departureTime;
private String departureTimeStr;
public String getDepartureTimeStr() {
if(departureTime != null){
departureTimeStr = DateFromatUtils.date2String(departureTime,"yyyy-MM-dd HH:mm");
}
return departureTimeStr;
}
DateFromatUtils:
public class DateFromatUtils {
/**
* 日期轉時間
* @param date
* @param patt
* @return
*/
public static String date2String(Date date, String patt){
SimpleDateFormat sdf = new SimpleDateFormat(patt);
String format = sdf.format(date);
return format;
}
/**
* 字符串轉日期
* @param time
* @param patt
* @return
*/
public static Date string2Date(String time, String patt){
SimpleDateFormat sdf = new SimpleDateFormat(patt);
try {
Date date = sdf.parse(time);
return date;
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("日期轉換異常");
}
}
}
對於特殊的標記屬性在頁面的展現(get方法須要注意)
與日期相似,建立額外表示的字段
/**
* 狀態 0 關閉 1 開啓
*/
private Integer productStatus;
/**
* 對狀態的字符串描述
*/
private String productStatusStr;
public String getProductStatusStr() {
if(null != productStatus){
if(productStatus == 0){
productStatusStr = "關閉";
} else if(productStatus == 1){
productStatusStr = "開啓";
}
}
return productStatusStr;
}
Mybatis的一對一和多對多的回顧:
一對一:
@Select("select * from orders")
@Results({
@Result(id = true,property = "id", column = "ID"),
@Result(property = "orderNum",column = "ORDERNUM"),
@Result(property = "orderTime",column = "ORDERTIME"),
@Result(property = "orderStatus",column = "ORDERSTATUS"),
@Result(property = "peopleCount",column = "PEOPLECOUNT"),
@Result(property = "payType",column = "PAYTYPE"),
@Result(property = "orderDesc",column = "ORDERDESC"),
@Result(property = "product",column = "PRODUCTID",javaType = Product.class,
one = @One(select = "cn.wzlove.mapper.ProductMapper.findProductById"))
})
多對多:
@Select("select * from orders where id = #{ordersId}")
@Results({
@Result(id = true,property = "id", column = "ID"),
@Result(property = "orderNum",column = "ORDERNUM"),
@Result(property = "orderTime",column = "ORDERTIME"),
@Result(property = "orderStatus",column = "ORDERSTATUS"),
@Result(property = "peopleCount",column = "PEOPLECOUNT"),
@Result(property = "payType",column = "PAYTYPE"),
@Result(property = "orderDesc",column = "ORDERDESC"),
@Result(property = "product",column = "PRODUCTID",javaType = Product.class,
one = @One(select = "cn.wzlove.mapper.ProductMapper.findProductById")),
@Result(property = "member",column = "MEMBERID",javaType = Member.class,
one = @One(select = "cn.wzlove.mapper.MemberMapper.findMemberById")),
@Result(property = "travellers",column = "id",javaType = java.util.List.class,
many = @Many(select = "cn.wzlove.mapper.TravellerMapper.findTravelByOrderId"))
})
PageHelper的使用:
1. 導入依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
2. 進行配置
<!--配置sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="cn.wzlove.domain"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<props>
<prop key="helperDialect">oracle</prop>
<prop key="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
3. 進行使用
@RequestMapping("findAll.do")
public ModelAndView findOrdersAll(@RequestParam(name = "page",required = true,defaultValue = "1") Integer page,
@RequestParam(name = "size",required = true,defaultValue = "4") Integer size){
ModelAndView mv = new ModelAndView();
PageHelper.startPage(page,size);
List<Orders> allOrders = ordersService.findAllOrders();
PageInfo<Orders> pageInfo = new PageInfo<>(allOrders);
mv.addObject("pageInfo",pageInfo);
mv.setViewName("orders-list");
return mv;
}
4. 對於PageInfo考慮查看源碼看看封裝的分頁信息,列出經常使用的
//當前頁
private int pageNum;
//每頁的數量
private int pageSize;
//當前頁的數量
private int size;
//因爲startRow和endRow不經常使用,這裏說個具體的用法
//能夠在頁面中"顯示startRow到endRow 共size條數據"
//當前頁面第一個元素在數據庫中的行號
private int startRow;
//當前頁面最後一個元素在數據庫中的行號
private int endRow;
//總記錄數
private long total;
//總頁數
private int pages;
//結果集
private List<T> list;
//前一頁
private int prePage;
//下一頁
private int nextPage;
權限的管理(Srping security的使用)
1. Srping security的使用: 安全框架(認證和受權)
1. 導入依賴
spring-security-web
spring-security-config
2. web.xml配置過濾器
ContextLoaderListener----------> 加載spring-Security.xml的配置文件
DelegatingFilterProxt----------> 委託過濾器代理類-----> springSecurityFilterChain(名字不能變)
3. spring-security核心配置文件的配置
1. 哪些資源不登陸也能訪問,也就是過濾
<security:http pattern="" security="none" >
2. 認證管理器
<security:authentication-manager>
3. 配置攔截規則
<security:http auto-config="true" use-expressions="false">
代碼以下:
2. web.xml的配置:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<!--
classpath和classpath*的區別
前者表示當前工程的類路徑下加載配置文件
後者表示從當前工程的類路徑及jar包的類路徑下加載
-->
<param-value>
classpath*:applicationContext.xml,
classpath*:spring-security.xml
</param-value>
</context-param>
3. spring-security.xml的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不攔截的資源 -->
<security:http pattern="/login.jsp" security="none"/>
<security:http pattern="/failer.jsp" security="none"/>
<security:http pattern="/css/**" security="none"/>
<security:http pattern="/img/**" security="none"/>
<security:http pattern="/plugins/**" security="none"/>
<!--
配置具體的規則
auto-config="true" 不用本身編寫登陸的頁面,框架提供默認登陸頁面
use-expressions="false" 是否使用SPEL表達式(沒學習過)
-->
<!-- 配置具體的攔截的規則 pattern="請求路徑的規則" access="訪問系統的人,必須有ROLE_USER的角色" -->
<security:http auto-config="true" use-expressions="false">
<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>
<!-- 定義跳轉的具體的頁面 -->
<security:form-login
login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/pages/main.jsp"
/>
<!-- 關閉跨域請求 -->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp" />
</security:http>
<!-- 切換成數據庫中的用戶名和密碼 -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<!-- 配置加密的方式(開始的時候因爲密碼沒有加密,因此將這個應該先註釋掉,等到密碼加密了再放開) -->
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密類 -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!-- 提供了入門的方式,在內存中存入用戶名和密碼
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
-->
<!--若是密碼沒有加密,則密碼前須要添加{noop}-->
</beans>
Spring Security的權限控制
服務器的權限控制
1. JSR250註解配置
1. 在pom.xml中引入依賴
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
2. 在spring-security.xml的配置文件中開啓註解開關
<security:global-method-security jsr250-annotations="enabled"></security:global-method-security>
3. 在方法上使用註解(通常在Controller註解上)
@RolesAllowed({"ADMIN","USER"}) ====> 必須有ADMIN或者USER角色才能夠訪問此方法
@PermitAll ====> 容許全部的角色均可以訪問
@DenyAll ====> 全部的角色都不能夠訪問
2. 使用@Secured註解
1. 在spring-security.xml的配置文件中開啓註解開關
<security:global-method-security secured-annotations="enabled"></security:global-method-security>
2. 使用註解
@Secured("ROLE_ADMIN") ====> 擁有ADMIN角色的用戶能夠訪問,必需要有ROLE_
3. 基於表達式的
1. 在配置文件中開啓註解開關
<security:global-method-security pre-post-annotations="enabled" ></security:global-method-security>
2. @PreAuthorize("hasRole('ROLE_ADMIN')") ====> 若是表達式返回true,能夠訪問該方法,因爲使用了spel表達式,因此配置文件須要更改(在原來的基礎上,修改use-expressions和access):
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
@PreAuthorize("authentication.principal.username == 'wzlove'")表示只有wzlove用戶能夠訪問
前端的權限控制
1. 在pom.xml中引入依賴
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
2. 在jsp頁面引入標籤庫:
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
3. 標籤的使用:
1. 獲取當前登陸的用戶名
<security:authentication property="principal.username"/>
2. 根據權限隱藏標籤(擁有ADMIN角色才能夠顯示該標籤)
<security:authorize access="hasRole('ADMIN')">
<li id="system-setting"><a
href="${pageContext.request.contextPath}/user/findAll"> <i
class="fa fa-circle-o"></i> 用戶管理
</a></li>
</security:authorize>
SpringAOP的日誌記錄控制(把數據存放在數據庫中)
1. 建立數據庫的表結構:
CREATE TABLE sysLog(
id VARCHAR2(32) default SYS_GUID() PRIMARY KEY,
visitTime timestamp,
username VARCHAR2(50),
ip VARCHAR2(30),
url VARCHAR2(50),
executionTime int,
method VARCHAR2(200)
)
2. 建立日誌實體:
public class SysLog {
/**
* 主鍵uuid
*/
private String id;
/**
* 訪問時間
*/
private Date visitTime;
/**
* 訪問時間前臺展現
*/
private String visitTimeStr;
/**
* 操做者
*/
private String username;
/**
* 操做者ip
*/
private String ip;
/**
* 操做的URL
*/
private String url;
/**
* 執行的時長
*/
private Long executionTime;
/**
* 訪問方法
*/
private String method;
setter和getter
}
4. 建立mapper:
@Mapper
public interface SysLogMapper {
@Insert("insert into syslog(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})")
void saveSysLog(SysLog sysLog);
@Select("select * from syslog")
List<SysLog> findAll();
}
5. AOP控制:
@Component
@Aspect
public class LogAop {
@Autowired
private HttpServletRequest request;
@Autowired
private SysLogService sysLogService;
@Around("execution(* cn.wzlove.controller.*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object proceed = null;
// 訪問方法(分別獲取類和方法,而後進行拼接)
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
// 忽略日誌自己的Controller
if("cn.wzlove.controller.SysLogController".equals(className)){
// 獲取參數
Object[] args = pjp.getArgs();
// 執行原始方法(放行)
proceed = pjp.proceed(args);
} else{
// 封裝SysLog,獲取SysLog的屬性
// 訪問時間
Date visitDate = new Date();
// 操做者
String loginName = SecurityContextHolder.getContext().getAuthentication().getName();
// 操做者ip
String remoteAddr = request.getRemoteAddr();
// 操做的URL
String requestURI = request.getRequestURI();
// 執行時長
Long startTime = System.currentTimeMillis();
// 獲取參數
Object[] args = pjp.getArgs();
// 執行原始方法(放行)
proceed = pjp.proceed(args);
// 結束時間
Long endTime = System.currentTimeMillis();
Long executeTime = endTime - startTime;
// 封裝SysLog
SysLog sysLog = new SysLog();
sysLog.setIp(remoteAddr);
sysLog.setExecutionTime(executeTime);
sysLog.setMethod(className+"."+methodName);
sysLog.setUsername(loginName);
sysLog.setVisitTime(visitDate);
sysLog.setUrl(requestURI);
// 進行插入操做
sysLogService.saveSysLog(sysLog);
}
return proceed;
}
}
6. 日誌的Controller
@Controller
@RequestMapping("sysLog")
public class SysLogController {
@Autowired
private SysLogService sysLogService;
@RequestMapping("findAll")
public ModelAndView findAll(){
ModelAndView mv = new ModelAndView();
List<SysLog> all = sysLogService.findAll();
mv.addObject("sysLogs",all);
mv.setViewName("syslog-list");
return mv;
}
}