SSM黑马旅游网项目随记

image-20210728200848296

image-20210728200852882

maven父子工程安装tomcat插件

在父工程的pom.xml中配置插件

image-20210728203804673

代码

  <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8080</port>
                </configuration>
                <version>2.2</version>
            </plugin>
        </plugins>

配置maven

image-20210728203906326

局部类型转换(字符串转为日期)

image-20210729102401980

image-20210729103104913

当用数字(0,1,2)表示某种状态时,常常会跟一个字符串描述,在数据库中存状态数字,在页面上用字符串描述显示

旅游业务对应的产品就一个(一对一)

当实体类里面有日期类型时,可以定义一个日期字符串,然后在get获取时,做一些处理

image-20210729173554327

image-20210729173624431

image-20210729173519209

image-20210729173641749

image-20210729173711140

订单的分页查询

插件实现:

1、添加jar包

 <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.2</version>
        </dependency>

2、在applicationContext.xml里面配置插件

 <!--配置sqlsessionfactorybean-->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 传入PageHelper的插件 -->
        <property name="plugins">
            <array>
                <!-- 传入插件的对象 -->
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <props>
                            <prop key="helperDialect">mysql</prop>
                            <prop key="reasonable">true</prop>
                        </props>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

3、在分页方法调用之前调用方法

package com.itheima.ssm.service.impl;

import com.github.pagehelper.PageHelper;
import com.itheima.dao.OrderDao;
import com.itheima.ssm.domain.Orders;
import com.itheima.ssm.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
//@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderDao orderDao;

    @Override
    public List<Orders> findAll( int page,int size) {
        /*分页操作:
        * 参数: pageNum 是页码值
        * 参数: pageSize 代表是每页显示条数
        * 必须真正调用分页方法之前!!!(紧挨着)*/
        PageHelper.startPage(page,size);
        return orderDao.findAll();
    }

    @Override
    public Orders findById(Integer id) {
        return orderDao.findById(id);
    }
}

控制器代码:

  //分页
  @RequestMapping("/findAll")
  public ModelAndView findAll(int page,int size){
      ModelAndView mv=new ModelAndView();
      List<Orders> orders = orderService.findAll(page,size);

      /*ordes集合里面不知有查到的数据,还有一些关于分页的数据,
      构建PageInfo对象,将它传递过去,pageinfo会自己处理这些数据
      PageInfo就是一个分页Bean*/
      PageInfo pageInfo=new PageInfo(orders);

      mv.addObject("pageInfo",pageInfo);
      mv.setViewName("orders-page-list");
      return mv;

  }

orders-page-list.jsp

	<!-- .box-footer-->
                <div class="box-footer">
                    <div class="pull-left">
                        <div class="form-group form-inline">
                            总共2 页,共14 条数据。 每页
                            <select class="form-control" id="changePageSize" οnchange="changePageSize()">
                                <option>1</option>
                                <option>2</option>
                                <option>3</option>
                                <option>4</option>
                                <option>5</option>
                            </select> 条
                        </div>
                    </div>

                    <div class="box-tools pull-right">
                        <ul class="pagination">
                            <li>
                                <a href="${pageContext.request.contextPath}/orders/findAll?page=1&size=${pageInfo.pageSize}" aria-label="Previous">首页</a>
                            </li>
                            <li><a href="${pageContext.request.contextPath}/orders/findAll?page=${pageInfo.pageNum-1}&size=${pageInfo.pageSize}">上一页</a></li>

							<%--中间页码用循环实现,从1开始,到总页数,每次加1--%>
                           <c:forEach begin="1" end="${pageInfo.pages}" var="pageNum">
							   <li><a href="${pageContext.request.contextPath}/orders/findAll?page=${pageNum}&size=${pageInfo.pageSize}">${pageNum}</a></li>
						   </c:forEach>
                            <li><a href="${pageContext.request.contextPath}/orders/findAll?page=${pageInfo.pageNum+1}&size=${pageInfo.pageSize}">下一页</a></li>
                            <li>
                                <a href="${pageContext.request.contextPath}/orders/findAll?page=${pageInfo.pages}&size=${pageInfo.pageSize}" aria-label="Next">尾页</a>
                            </li>
                        </ul>
                    </div>

                </div>
                <!-- /.box-footer-->
pageInfo.pageSize:每页的条数

pageNum: 当前页

pageSize:每页的数量

size:当前页的数量

pages:总页数

spring security

在xml配置文件中创建用户

image-20210730090701180

不用再配置tomcat,直接用插件

它会自己创建登陆页面

403: 权限不足的问题

spring security 自定义页面

失败是用户名和密码匹配失败,权限不足也会跳转到默认页面,而不是跳转到失败页面(因为权限不足的用户账号和密码可以匹配)

使用数据库完成spring security 认证操作

image-20210730103604991

在整合的ssm项目中用spring security

1、导入jar包

2、在web.xml中配置

image-20210730105450091 image-20210730105510929

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表达式(没学习过)
    -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
        <security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>

        <!-- 定义跳转的具体的页面 -->
        <security:form-login
                login-page="/login.jsp"
                login-processing-url="/login.do"
                default-target-url="/index.jsp"
                authentication-failure-url="/failer.jsp"
                authentication-success-forward-url="/main.jsp"
        />

        <!-- 关闭跨域请求 -->
        <security:csrf disabled="true"/>

        <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout.do" 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>
    -->

</beans>


image-20210730105336908

在spring-security.xml中定义了登录页面,登录的路径,成功页面,失败页面,还定义了认证操作具体的service(原来由Controller来完成的操作,现在由spring security完成)

User类继承了UserDetails,所以当返回值类型是UserDetails时,可以返回User对象, 并且其构造方法参数也如图所示

image-20210730112816068

userServiceImpl

package com.itheima.ssm.service.impl;

import com.itheima.dao.UserInfoDao;
import com.itheima.ssm.domain.UserInfo;
import com.itheima.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserInfoDao userInfoDao;

    /*因为UserService继承了UserDetailsService 接口,所以他的实现类要实现UserDetailsService 接口里面的方法*/
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //调用方法查询数据库中的用户
        UserInfo userInfo=userInfoDao.findUserByName(s);
      //处理自己的数据库用户封装成UserDetails
        User user=new User(userInfo.getUsername(),userInfo.getPassword(),getAuthority());

        /*User类继承了UserDetails,所以当返回值类型是UserDetails时,可以返回User对象*/
        return user;
    }

    //作用就是返回一个List集合,集合中装入的是角色描述
    public List<SimpleGrantedAuthority> getAuthority(){

        List<SimpleGrantedAuthority>  list=new ArrayList<>();
        list.add(new SimpleGrantedAuthority("ROLE_USER"));
        return  list;

    }
}

此时应该注意的是:角色的名称是我们手动赋予的(根据spring-security配置文件里面的名称),但是其实应该是从数据库中给获取。

获取数据库的角色信息

利用spring-security完成用户退出

1、在配置文件spring-security中配置

  <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />

销毁session,指定跳转的路径,指定成功后跳转到登陆页面

2、image-20210730163335441

完成上述操作即可

加密

因为之前数据库没有加密,密码是明文的,所以获取密码前要加{noop},但是加密后就不需要了。

加密后用户登录时要进行处理

1、在配置文件中告诉他用户密码加密了

<?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表达式(没学习过)
    -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
        <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.do" 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>
    -->

</beans>


2、UserServiceImpl中去掉{noop}

 public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //调用方法查询数据库中的用户
        UserInfo userInfo=userInfoDao.findUserByName(s);
      //处理自己的数据库用户封装成UserDetails
        //User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));
        User user=new User(userInfo.getUsername(),userInfo.getPassword(),userInfo.getStatus()==0?false:true,true,true,true,getAuthority(userInfo.getRoles()));

        //System.out.println(user.getUsername()+"+"+user.getPassword());

        /*User类继承了UserDetails,所以当返回值类型是UserDetails时,可以返回User对象*/
        return user;
    }

新用户添加实行密码加密后,原来的老用户发现登录失败,因为密码是明文的问题。这个时候需要将数据库中的老用户的密码改成加密后的(利用加密工具类),当然你也可以把老用户删了再新建(数据不多)

加密工具类

package com.itheima.ssm.utils;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class BCryptPasswordEncoderUtils {
    private static BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
    public static String encodePassword(String password){
        
        return bCryptPasswordEncoder.encode(password);
    }

    public static void main(String[] args) {
        String password="tom";
        String pwd = encodePassword(password);
        
        System.out.print(pwd;
    }
}

修改后的users表

image-20210731093339567

将数据库中的日期转换成字符串(框架不能帮我们转换的)在页面上显示,可以利用工具类(有局部的和全局的)

局部的日期转换工具类

package com.itheima.ssm.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtils {

    //日期转换为字符串
    public static String dateToString(Date date,String patt){
        SimpleDateFormat sdf=new SimpleDateFormat(patt);
        String format=sdf.format(date);
        return format;
    }

    //字符串转换为日期
    public static Date stringToDate(String str, String patt) throws Exception {
        SimpleDateFormat sdf=new SimpleDateFormat(patt);
        Date parse=sdf.parse(str);
        return parse;
    }
}

在需要日期转换的实体类中使用

Product.java

package com.itheima.ssm.domain;

import com.itheima.ssm.utils.DateUtils;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

public class Product implements Serializable {
    private Integer id; // 主键
    private  String idStr;

    private String productNum; // 编号 唯一
    private String productName; // 名称
    private String cityName; // 出发城市

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date departureTime; // 出发时间
    private String departureTimeStr;

    private double productPrice; // 产品价格
    private String productDesc; // 产品描述

    private Integer productStatus; // 状态 0 关闭 1 开启
    private String productStatusStr;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getIdStr() {
        return idStr;
    }

    public void setIdStr(String idStr) {
        this.idStr = idStr;
    }

    public String getProductNum() {
        return productNum;
    }

    public void setProductNum(String productNum) {
        this.productNum = productNum;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public Date getDepartureTime() {
        return departureTime;
    }

    public void setDepartureTime(Date departureTime) {
        this.departureTime = departureTime;
    }

    public String getDepartureTimeStr() {
        if(departureTime!=null){
            //将日期转换为字符串
            departureTimeStr= DateUtils.dateToString(departureTime,"yyyy-MM-dd HH:mm");
        }
        return departureTimeStr;
    }

    public void setDepartureTimeStr(String departureTimeStr) {
        this.departureTimeStr = departureTimeStr;
    }

    public double getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(double productPrice) {
        this.productPrice = productPrice;
    }

    public String getProductDesc() {
        return productDesc;
    }

    public void setProductDesc(String productDesc) {
        this.productDesc = productDesc;
    }

    public Integer getProductStatus() {
        return productStatus;
    }

    public void setProductStatus(Integer productStatus) {
        this.productStatus = productStatus;
    }

    public String getProductStatusStr() {
        //因为页面上获取的是ProductStatusStr,
        // 而数据库中获取的是ProductStatus,所以要对他进行处理
        if (productStatus!=null){
            // 状态 0 关闭 1 开启
            if(productStatus==0){
                productStatusStr="关闭";
            }
            if (productStatus == 1) {
                productStatusStr="开启";
            }


        }
        return productStatusStr;
    }

    public void setProductStatusStr(String productStatusStr) {

        this.productStatusStr = productStatusStr;
    }
}


也可以使用全局的工具类,需要实现Converter< T>接口

查询用户详情

查询用户详情和查询订单详情是有区别的

用户查询

image-20210731095631739

image-20210731095535194

控制器

 /*根据用户id查找,用于用户详情
    * 注意:用户详情里面还有角色和权限信息*/
    @RequestMapping("/findById")
    public ModelAndView findById(Integer id){
        ModelAndView mv=new ModelAndView();
        UserInfo userInfo=userService.findById(id);
        mv.addObject("user",userInfo);
        mv.setViewName("user-show");
        return mv;
    }

userService

  /*根据用户id查找用户*/
    UserInfo findById(Integer id);

@Override
    public UserInfo findById(Integer id) {
        return userInfoDao.findById(id);
    }

userinfodao

   /*根据id查找,用户详情里面还有角色和权限信息
    !!!!!!!!注意此dao中的写法,不会写,不会查找权限信息(在查找角色的时候把权限信息也查询出来,封装到角色信息里)
    * */
    @Select("select * from users where id=#{id}")
    @Results({
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "username",column = "username"),
            @Result(property = "email",column = "email"),
            @Result(property = "password",column = "password"),
            @Result(property = "phoneNum",column = "phoneNum"),
            @Result(property = "status",column = "status"),
            @Result(property = "roles",column = "id",javaType = java.util.List.class,many = @Many(select = "com.itheima.dao.RoleDao.findByUserId"))

    })
    UserInfo findById(Integer id);

RoleDao

/*根据用户id查找的角色,同时还有角色下的权限信息*/
    @Select("SELECT * FROM role WHERE id IN(SELECT roleId FROM users_role WHERE userId=#{userId})")
    @Results({
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "roleName",property = "roleName"),
            @Result(column = "roleDesc",property = "roleDesc"),
            @Result(column = "id",property = "permissions",javaType = java.util.List.class,many = @Many(select = "com.itheima.dao.PermissionDao.findByRoleId"))

    })
    List<Role> findByUserId(Integer userId);

PermissionDao

/*根据角色id查找权限*/
    @Select("select * from permission where id in (select permissionId from role_permission where roleId=#{roleId})")
    List<Permission> findByRoleId(Integer roleId);

user-show.jsp(正文)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版">

<!-- Tell the browser to be responsive to screen width -->
<meta
	content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"
	name="viewport">

</head>

<body class="hold-transition skin-blue sidebar-mini">

	<div class="wrapper">

		<!-- 页面头部 -->
		<jsp:include page="header.jsp"></jsp:include>
		<!-- 页面头部 /-->

		<!-- 导航侧栏 -->
		<jsp:include page="aside.jsp"></jsp:include>
		<!-- 导航侧栏 /-->

		<!-- 内容区域 -->
		<div class="content-wrapper">

			<!-- 内容头部 -->
			<section class="content-header">
			<h1>
				用户管理 <small>全部用户</small>
			</h1>
			<ol class="breadcrumb">
				<li><a href="${pageContext.request.contextPath}/index.jsp"><i
						class="fa fa-dashboard"></i> 首页</a></li>
				<li><a
					href="${pageContext.request.contextPath}/user/findAll">用户管理</a></li>

				<li class="active">全部用户</li>
			</ol>
			</section>
			<!-- 内容头部 /-->

			<!-- 正文区域 -->
			<section class="content"> <!-- .box-body -->
			<div class="box box-primary">
				<div class="box-header with-border">
					<h3 class="box-title">列表</h3>
				</div>

				<div class="box-body">

					<!-- 数据表格 -->
					<div class="table-box">

						<!--工具栏-->
						<div class="pull-left">
							<div class="form-group form-inline">
								<div class="btn-group">
									<button type="button" class="btn btn-default" title="新建">
										<i class="fa fa-file-o"></i> 新建
									</button>

									<button type="button" class="btn btn-default" title="刷新">
										<i class="fa fa-refresh"></i> 刷新
									</button>
								</div>
							</div>
						</div>
						<div class="box-tools pull-right">
							<div class="has-feedback">
								<input type="text" class="form-control input-sm"
									placeholder="搜索"> <span
									class="glyphicon glyphicon-search form-control-feedback"></span>
							</div>
						</div>
						<!--工具栏/-->

						<!--数据列表-->
						<div class="tab-pane" id="tab-treetable">
							<table id="collapse-table"
								class="table table-bordered table-hover dataTable">
								<thead>
									<tr>
										<th>名称</th>
										<th>描述</th>
									</tr>
								</thead>

								<tr data-tt-id="0">
									<td colspan="2">${user.username}</td>
								</tr>

								<tbody>
									<c:forEach items="${user.roles}" var="role">
										<tr data-tt-id="1" data-tt-parent-id="0">
											<td>${role.roleName }</td>
											<td>${role.roleDesc }</td>
										</tr>
										<c:forEach items="${role.permissions}" var="permission">
											<tr data-tt-id="1-1" data-tt-parent-id="1">
												<td>${permission.permissionName}</td>
												<td>${permission.url}</td>
											</tr>

										</c:forEach>
									</c:forEach>
								</tbody>
							</table>
						</div>
						<!--数据列表/-->

					</div>
					<!-- 数据表格 /-->

				</div>
				<!-- /.box-body -->

				<!-- .box-footer-->
				<div class="box-footer">
					<div class="pull-left">
						<div class="form-group form-inline">
							总共2 页,共14 条数据。 每页 <select class="form-control">
								<option>1</option>
								<option>2</option>
								<option>3</option>
								<option>4</option>
								<option>5</option>
							</select> 条
						</div>
					</div>

					<div class="box-tools pull-right">
						<ul class="pagination">
							<li><a href="#" aria-label="Previous">首页</a></li>
							<li><a href="#">上一页</a></li>
							<li><a href="#">1</a></li>
							<li><a href="#">2</a></li>
							<li><a href="#">3</a></li>
							<li><a href="#">4</a></li>
							<li><a href="#">5</a></li>
							<li><a href="#">下一页</a></li>
							<li><a href="#" aria-label="Next">尾页</a></li>
						</ul>
					</div>

				</div>
				<!-- /.box-footer-->

			</div>

			</section>
			<!-- 正文区域 /-->

		</div>
		<!-- @@close -->
		<!-- 内容区域 /-->

		<!-- 底部导航 -->
		<footer class="main-footer">
		<div class="pull-right hidden-xs">
			<b>Version</b> 1.0.8
		</div>
		<strong>Copyright &copy; 2014-2017 <a
			href="http://www.itcast.cn">研究院研发部</a>.
		</strong> All rights reserved. </footer>
		<!-- 底部导航 /-->

	</div>



</body>

</html>

订单查询:

image-20210731095739922

image-20210731095842783

order类

package com.itheima.ssm.domain;

import com.itheima.ssm.utils.DateUtils;

import java.util.Date;
import java.util.List;

//订单
public class Orders {
    private int id;
    private String orderNum;
    private Date orderTime;
    private String orderTimeStr;
    private int orderStatus;
    private String orderStatusStr;
    private int peopleCount;
    private Product product;
    private List<Traveller> travellers;
    private Member member;
    private Integer payType;
    private String payTypeStr;
    private String orderDesc;

    public String getOrderStatusStr() {
        //订单状态(0 未支付 1 已支付)
        if(orderStatus==0){
            orderStatusStr="未支付";
        }else if(orderStatus==1){
            orderStatusStr="已支付";
        }
        return orderStatusStr;
    }

    public void setOrderStatusStr(String orderStatusStr) {
        this.orderStatusStr = orderStatusStr;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getOrderNum() {
        return orderNum;
    }

    public void setOrderNum(String orderNum) {
        this.orderNum = orderNum;
    }

    public Date getOrderTime() {
        return orderTime;
    }

    public void setOrderTime(Date orderTime) {
        this.orderTime = orderTime;
    }

    public String getOrderTimeStr() {
        if(orderTime!=null){
            //将日期转换为字符串
            orderTimeStr= DateUtils.dateToString(orderTime,"yyyy-MM-dd HH:mm");
        }
        return orderTimeStr;
    }

    public void setOrderTimeStr(String orderTimeStr) {
        this.orderTimeStr = orderTimeStr;
    }

    public int getOrderStatus() {
        return orderStatus;
    }

    public void setOrderStatus(int orderStatus) {
        this.orderStatus = orderStatus;
    }

    public int getPeopleCount() {
        return peopleCount;
    }

    public void setPeopleCount(int peopleCount) {
        this.peopleCount = peopleCount;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public List<Traveller> getTravellers() {
        return travellers;
    }

    public void setTravellers(List<Traveller> travellers) {
        this.travellers = travellers;
    }

    public Member getMember() {
        return member;
    }

    public void setMember(Member member) {
        this.member = member;
    }

    public Integer getPayType() {
        return payType;
    }

    public void setPayType(Integer payType) {
        this.payType = payType;
    }

    public String getPayTypeStr() {
        //支付方式(0 支付宝 1 微信 2其它)
        if(payType==0){
            payTypeStr="支付宝";
        }else if(payType==1){
            payTypeStr="微信";
        }else if(payType==2){
            payTypeStr="其它";
        }
        return payTypeStr;
    }

    public void setPayTypeStr(String payTypeStr) {
        this.payTypeStr = payTypeStr;
    }

    public String getOrderDesc() {
        return orderDesc;
    }

    public void setOrderDesc(String orderDesc) {
        this.orderDesc = orderDesc;
    }
}

orderDao

package com.itheima.dao;

import com.itheima.ssm.domain.Member;
import com.itheima.ssm.domain.Orders;
import com.itheima.ssm.domain.Product;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface OrderDao {
    /*订单和产品之间是一对一的关系,用注解进行封装*/
    @Select("select * from orders")
    @Results({
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "orderNum",property = "orderNum"),
            @Result(column = "orderTime",property = "orderTime"),
            @Result(column = "orderStatus",property = "orderStatus"),
            @Result(column = "peopleCount",property = "peopleCount"),
            @Result(column = "payType",property = "payType"),
            @Result(column = "orderDesc",property = "orderDesc"),
            @Result(column = "productId",property = "product",one = @One(select = "com.itheima.dao.ProductDao.findById"))
    })
    List<Orders> findAll();

    //多表操作,既要查询订单信息,订单对应的商品信息,以及会员信息,游客信息
    //订单和游客是多对多
    //colum是指数据库中的名称,property是实体类中的名称
    @Select("select * from orders where id=#{id}")
    @Results({
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "orderNum",property = "orderNum"),
            @Result(column = "orderTime",property = "orderTime"),
            @Result(column = "orderStatus",property = "orderStatus"),
            @Result(column = "peopleCount",property = "peopleCount"),
            @Result(column = "payType",property = "payType"),
            @Result(column = "orderDesc",property = "orderDesc"),
            @Result(column = "productId",property = "product",javaType = Product.class,one = @One(select = "com.itheima.dao.ProductDao.findById")),
            @Result(column = "memberId",property = "member",javaType = Member.class,one=@One(select = "com.itheima.dao.MemberDao.findById")),
            @Result(column = "id",property = "travellers",javaType = java.util.List.class,many = @Many(select ="com.itheima.dao.TravellerDao.findByOrdersId" ))
    })
    Orders findById(Integer id);
}

orderServiceImpl

package com.itheima.ssm.service.impl;

import com.github.pagehelper.PageHelper;
import com.itheima.dao.OrderDao;
import com.itheima.ssm.domain.Orders;
import com.itheima.ssm.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
//@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderDao orderDao;

    @Override
    public List<Orders> findAll( int page,int size) {
        /*分页操作:
        * 参数: pageNum 是页码值
        * 参数: pageSize 代表是每页显示条数
        * 必须真正调用分页方法之前!!!(紧挨着)*/
        PageHelper.startPage(page,size);
        return orderDao.findAll();
    }

    @Override
    public Orders findById(Integer id) {
        return orderDao.findById(id);
    }
}

orders-show.jsp(只有正文)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版">

<!-- Tell the browser to be responsive to screen width -->
<meta
	content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"
	name="viewport">


<body class="hold-transition skin-blue sidebar-mini">

	<div class="wrapper">

		<!-- 页面头部 -->
		<jsp:include page="header.jsp"></jsp:include>
		<!-- 页面头部 /-->

		<!-- 导航侧栏 -->
		<jsp:include page="aside.jsp"></jsp:include>
		<!-- 导航侧栏 /-->

		<!-- 内容区域 -->
		<div class="content-wrapper">

			<!-- 内容头部 -->
			<section class="content-header">
			<h1>
				订单管理 <small>全部订单</small>
			</h1>
			<ol class="breadcrumb">
				<li><a href="all-admin-index.html"><i
						class="fa fa-dashboard"></i> 首页</a></li>
				<li><a href="all-order-manage-list.html">订单管理</a></li>
				<li class="active">订单详情</li>
			</ol>
			</section>
			<!-- 内容头部 /-->

			<!-- 正文区域 -->
			<section class="content"> <!--订单信息-->
			<div class="panel panel-default">
				<div class="panel-heading">订单信息</div>
				<div class="row data-type">

					<div class="col-md-2 title">订单编号</div>
					<div class="col-md-4 data">
						<input type="text" class="form-control" placeholder="订单编号"
							value="${orders.orderNum }" readonly="readonly">
					</div>

					<div class="col-md-2 title">下单时间</div>
					<div class="col-md-4 data">
						<div class="input-group date">
							<div class="input-group-addon">
								<i class="fa fa-calendar"></i>
							</div>
							<input type="text" class="form-control pull-right"
								id="datepicker-a3" readonly="readonly"
								value="${orders.orderTimeStr}">
						</div>
					</div>
					<div class="col-md-2 title">路线名称</div>
					<div class="col-md-4 data">
						<input type="text" class="form-control" placeholder="路线名称"
							value="${orders.product.productName }" readonly="readonly">
					</div>

					<div class="col-md-2 title">出发城市</div>
					<div class="col-md-4 data">
						<input type="text" class="form-control" placeholder="出发城市"
							value="${orders.product.cityName }" readonly="readonly">
					</div>

					<div class="col-md-2 title">出发时间</div>
					<div class="col-md-4 data">
						<div class="input-group date">
							<div class="input-group-addon">
								<i class="fa fa-calendar"></i>
							</div>
							<input type="text" class="form-control pull-right"
								id="datepicker-a6" value="${orders.product.departureTimeStr}"
								readonly="readonly">
						</div>
					</div>
					<div class="col-md-2 title">出游人数</div>
					<div class="col-md-4 data">
						<input type="text" class="form-control" placeholder="出游人数"
							value="${orders.peopleCount}" readonly="readonly">
					</div>

					<div class="col-md-2 title rowHeight2x">其他信息</div>
					<div class="col-md-10 data rowHeight2x">
						<textarea class="form-control" rows="3" placeholder="其他信息">
							${orders.orderDesc }
						</textarea>
					</div>

				</div>
			</div>
			<!--订单信息/--> <!--游客信息-->
			<div class="panel panel-default">
				<div class="panel-heading">游客信息</div>
				<!--数据列表-->
				<table id="dataList"
					class="table table-bordered table-striped table-hover dataTable">
					<thead>
						<tr>
							<th class="">人群</th>
							<th class="">姓名</th>
							<th class="">性别</th>
							<th class="">手机号码</th>
							<th class="">证件类型</th>
							<th class="">证件号码</th>
						</tr>
					</thead>
					<tbody>
						<c:forEach var="traveller" items="${orders.travellers}">

							<tr>
								<td>${traveller.travellerTypeStr}</td>
								<td><input type="text" size="10" value="${traveller.name }"
									readonly="readonly"></td>
								<td><input type="text" size="10" value="${traveller.sex }"
									readonly="readonly"></td>
								<td><input type="text" size="20"
									value="${traveller.phoneNum }" readonly="readonly"></td>
								<td><input type="text" size="15"
									value="${traveller.credentialsTypeStr}" readonly="readonly"></td>
								<td><input type="text" size="28"
									value="${traveller.credentialsNum }" readonly="readonly"></td>
							</tr>
						</c:forEach>


					</tbody>
				</table>
				<!--数据列表/-->
			</div>
			<!--游客信息/--> <!--联系人信息-->
			<div class="panel panel-default">
				<div class="panel-heading">联系人信息</div>
				<div class="row data-type">

					<div class="col-md-2 title">会员</div>
					<div class="col-md-4 data text">${orders.member.nickname }</div>

					<div class="col-md-2 title">联系人</div>
					<div class="col-md-4 data text">${orders.member.name}</div>

					<div class="col-md-2 title">手机号</div>
					<div class="col-md-4 data text">${orders.member.phoneNum}</div>

					<div class="col-md-2 title">邮箱</div>
					<div class="col-md-4 data text">${orders.member.email}</div>

				</div>
			</div>
			<!--联系人信息/--> <!--费用信息--> <c:if test="${orders.orderStatus==1}">
				<div class="panel panel-default">
					<div class="panel-heading">费用信息</div>
					<div class="row data-type">

						<div class="col-md-2 title">支付方式</div>
						<div class="col-md-4 data text">在线支付-${orders.payTypeStr}</div>

						<div class="col-md-2 title">金额</div>
						<div class="col-md-4 data text">¥${orders.product.productPrice}</div>

					</div>
				</div>
			</c:if> <!--费用信息/--> <!--工具栏-->
			<div class="box-tools text-center">

				<button type="button" class="btn bg-default"
					οnclick="history.back(-1);">返回</button>
			</div>
			<!--工具栏/--> </section>
			<!-- 正文区域 /-->


		</div>
		<!-- 内容区域 /-->

	
</body>


</html>

用户添加角色

image-20210731155645067

注意:

SSM框架传递多个参数时要使用注解@Param,否则会报错

image-20210731165349181

image-20210731165408173

正确写法:

image-20210731165946718

角色添加权限

和上面操作一样

服务器端方法级权限控制

使用注解进行权限限定

@RolesAllowed(“ADMIN”)

spring-security.xml

 <security:global-method-security jsr250-annotations="enabled"/>

在ProductController查找商品的方法上实验


/*查找商品*/
    @RolesAllowed("ADMIN")
    @RequestMapping("/findAll")
    public ModelAndView findAll(){
        ModelAndView mv=new ModelAndView();
        List<Product> products = productService.findAll();
         mv.addObject("productList",products);
         mv.setViewName("product-list");

        return mv;
    }

image-20210731212820778

可以在web.xml中配置出现403错误时要跳转的页面

image-20210731214513390

使用jsr250-annotations时可以把角色前面的ROLE_省略 ,使用下面的注解时角色前缀 ROLE _不能省略

@Secured(“ROLE_ADMIN”)

它不用导依赖

1、spring-mvc.xml

  <security:global-method-security secured-annotations="enabled"/>

2、在方法前使用

 /*插入商品*/
    @RequestMapping("/saveProduct")
    @Secured("ROLE_ADMIN")
    public String saveProduct(Product product){
        System.out.println(product);
        //调用方法插入
        productService.saveProduct(product);
        //插入后调到查找方法
        return "redirect:findAll";


    }

图示步骤:

image-20210801090217007

支持表达式的注解

1、spring-mvc.xml

<security:global-method-security pre-post-annotations="enabled"/>

2、在方法前使用

 @RequestMapping("/findAll")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public ModelAndView findAll(){
        ModelAndView mv=new ModelAndView();
        List<UserInfo> userInfoList=userService.findAll();
        mv.addObject("userList",userInfoList);
        mv.setViewName("user-list");
        return mv;

    }

    /*添加用户*/
    @RequestMapping("/save")
    @PreAuthorize("authentication.principal.username=='tom'")  //即只有tom才能进行用户的添加
    public String saveUser(UserInfo userInfo){

      userService.saveUserInfo(userInfo);

        return "redirect:/user/findAll";


    }

图示:

image-20210801091308359

记住上面的配置是在spring-mvc的配置文件中配置,同时还要加上spring-security的空间约束

页面端权限控制

1、导入依赖

<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、在jsp使用标签

principal:代表现在正在操作的对象

image-20210801102441824

图解步骤:

image-20210801103746403

image-20210801103142469

但是如果你要在jsp页面使用权限控制表达式,这里需要做出改变。

eg:

image-20210801103445860

image-20210801103528548

SSMAOP日志

记录你对系统的操作

1、信息获取

图解:

image-20210801150355425

代码:

package com.itheima.controller;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect
public class LogAop {

    //配置后,自定注入request
    @Autowired
    private HttpServletRequest request;

    private Date visitiTime;//开始时间
    private Class clazz;//访问的类
    private Method method;//访问的方法


    //前置通知   主要获取开始时间,执行得类是哪一个,执行的是哪一个方法
    @Before("execution(* com.itheima.controller.*.*(..))")
    public void doBefore(JoinPoint jp) throws Exception {
        visitiTime=new Date();//当前时间就是开始访问的时间
        clazz=jp.getTarget().getClass();//具体要访问的类
        String  methodName=jp.getSignature().getName();//获取访问的方法的名称
        Object[] args = jp.getArgs();//获取访问的方法的参数

        //获得具体执行的Method对象
        if (args == null || args.length==0) {
            method=clazz.getMethod(methodName); //只能获得无参的方法
        }else{
            Class[] classAres=new Class[args.length];
            //把每一个参数的class拿到放在Class数组里
            for (int i = 0; i <args.length ; i++) {
                classAres[i]=args[i].getClass();
            }
            clazz.getMethod(methodName,classAres);//获得有参方法
        }


    }
    //后置通知
    @After("execution(* com.itheima.controller.*.*(..))")
    public void doAfter(JoinPoint jp){
        //获得访问时长
        long time = new Date().getTime() - visitiTime.getTime();

        //获得url,通过反射对注解进行操作
        String url="";
        if(clazz!=null && method!=null && clazz!=LogAop.class ){
            //1.获得类上的@RequestMapping("/orders")
            RequestMapping clazzAnnotation =(RequestMapping) clazz.getAnnotation(RequestMapping.class);
            if (clazzAnnotation != null) {
                String[] classValue = clazzAnnotation.value();

                //2.获得方法上的@RequestMapping("/。。")
                RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
                if (methodAnnotation != null) {
                    String[] methodValue = methodAnnotation.value();

                    url=classValue[0]+methodValue[0];
                }

            }
        }
    }


    //获取当前的ip
    String ip=request.getRemoteAddr();

    //获得用户名
    //1、从上下文中获得了当前登录的用户
    SecurityContext context= SecurityContextHolder.getContext();
    User user= (User) context.getAuthentication().getPrincipal();//获得操作对象
    String username=user.getUsername(); //获得对象的名称


}

2、插入数据库

和之前的商品插入用户插入等方法一样

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>cn.itcast.parent</groupId> <artifactId>itcast-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>cn.itcast</groupId> <artifactId>travel</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> <!-- 连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <!-- Jackson Json处理工具包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> </dependency> </dependencies> <build> <plugins> <!-- 配置Tomcat插件 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <port>8080</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值