1 Star 0 Fork 57

xihongshi / Java Web教学项目

forked from Albert / Java Web教学项目 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

Java Web教学项目

#——基于MVC的博客网站设计与实现

该项目是基于MVC的Java Web基础教学项目,不涉及前端内容。相关的前端内容请访问同账号的其他项目。

该项目为至少要运行在JDK1.8环境中,建议运行在JDK 9或JDK 10中;服务器建议使用tomcat 9或Jetty 12版本。

#1,软件架构

最基础的MVC模式:JSP+Servlet+JavaBean结构,使用maven构建和管理,使用git进行版本控制。

使用JSTL/EL、原生AJAX等技术。

#2,前置任务列表

完成该项目需要一些首先完成一些前置任务。在掌握前置任务之后,才能完成该项目

##1,构建基于maven的项目

###maven介绍

maven是基于apache管理的进行java项目构建、jar包管理软件。主要的作用是使用最佳实践管理java项目和jar包间的依赖关系。

本项目的就是构建基于maven的web项目,所有的第三方jar包都依赖于中央仓库。

与依赖与某种IDE构建的项目不同,依赖于maven构建的项目在所有IDE中都保持相同的结构。其结构如下:

下载地址及安装

地址:https://maven.apache.org/

maven不需要安装,只解压就可以使用了。但使用使用前需要进行部分配置工作。

###配置方案

配置maven\conf\settiong.xml文件

修改本地仓库的地址;新增镜像仓库地址

<localRepository>E:\yuhf\.m2\repository</localRepository>
<mirror>
    <id>alimaven</id>
    <mirrorOf>central</mirrorOf>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>

###Eclipse中的maven使用

Eclipse JavaEE版本默认包含maven插件。所以只需要对maven插件进行简单的配置就可以使用。

配置路径:windows->references->maven->user setting

配置主要是对maven软件的路径设置。包括全局setting.xml文件和局部setting.xml文件的指定。

###项目配置

配置pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0"
	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>
	<groupId>edu.yuhf</groupId>
	<artifactId>blogServer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.1.0</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<webResources>
						<resource>
							<directory>src/main/webapp</directory>
							<filtering>true</filtering>
							<targetPath>WEB-INF</targetPath>
						</resource>
					</webResources>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.eclipse.jetty</groupId>
				<artifactId>jetty-maven-plugin</artifactId>
				<version>9.4.5.v20170502</version>
				<configuration>
					<scanIntervalSeconds>10</scanIntervalSeconds>
					<httpConnector>
						<port>9000</port>
					</httpConnector>
					<contextPath>/</contextPath>
					<webAppConfig>
						<defaultsDescriptor>src/test/resources/webdefault.xml</defaultsDescriptor>
					</webAppConfig>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>12.1.0</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.49</version>
		</dependency>
	</dependencies>
	<packaging>war</packaging>
</project>

##2,利用Git控制项目版本

学会使用Git软件的用法,并确定远程仓库。本文建议使用码云。

使用Eclipse时,不需要专门安装Git软件,直接在Eclipse中就可以使用Git的相关功能。

##3,引入数据库访问工具类

###工具类

创建如下:java文件,完成数据库访问代码封装和优化,实现数据库连接信息软编码。 完成对一般的数据库操作(CRUD)的封装。可以返回实体类实例。 DBConnection.java

static{}
public Connection getConnection();
public void closeConnection(Connection connection);

JdbcTemplate.java

public List<T> query(String sql,ResultSetHandle rsh,Object...param);
public int queryForCount(String sql,Object...param);
public int update(String sql,Object...param);

ResultSetHandler.java --接口

TransactionManager.java

public class TransactionManager {
	public void beginTranscation() {}	//开启事务
	public void commitAndClose() {}		//提交并关闭事务
	public void rollbackandClose() {}	//回滚并关闭事务
}

jdbc.properties配置文件

###引入log4j日志系统

首先在pom.xml文件中添加依赖

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

之后添加log4j.properties配置文件

log4j.rootLogger=debug,console

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern= %d - %c -%-4r [%t] %-5p - %m%n

最后在每个要进行日志输出的类中的加入Logger的声明。如下:

private static Logger log=Logger.getLogger(DBConnection.class);
...
log.debug("....");
log.error("....");

###事务控制处理

增加了事务控制类,为此要对数据库连接类进行一些修改。

主要的目的是实现线程和connection引用对象的统一。关键是使用ThreadLocal类。ThreadLocal类的数据结构是Map。键是线程id,值可以放任何对象。

##4,数据库设计和表空间创建

使用PowerDesigner软件设计数据库的物理模型。基本参照如下:

1,用户信息管理模块:用户表、用户详情表、行政区划表、爱好表 2,文章信息管理模块:文章分类表、文章信息表 3,用户权限管理模:角色表、权限表、用户角色表、角色权限表

要求完成基本的设计工作,生成pdm文件。

###创建表空间和用户

create tablespace nnblog
datafile 'D:\app\Administrator\oradata\orcl\nnblog.dbf'
size 100m autoextend on next 20m;

create user nnblog identified by nnblog default tablespace nnblog;
grant connect to nnblog;
grant resource to nnblog;

##5,主页面布局准备

基于Grid,构建主页页面

#3,项目细分任务列表

##任务一,登录流程

###1,简单登录(不连接数据库)

创建不带数据库验证的用户登录流程。熟悉web开发中的基于MVC设计模式的开发流程。

注意,登录流程实际上包含两个相互独立的流程。

index.jsp-->init.servlet-->login.jsp					  流程1
login.jsp-->user.servlet-->login.jsp或veiws/main.jsp		 流程2

说明:尽量不要出现在页面直接转向另一个页面的情况。

###2,登录流程附加功能

在用户登录流程中,加入session验证、cookie校验功能。

1,session验证:用session保护所有需要身份验证才能访问的页面。

知识点:session、Filter

2,cookie验证:往访问者本机存入一个文本,称作cookie。任何网站都可以访问这些cookie。

知识点:cookie

综合知识:session和cookie区别?

3,Filter的概念和应用方法

知识点:AOP、过滤器的的应用、chain.doFilter()、过滤器链等

###3,表的创建工作

完成数据库的创建,创建nnblog表空间,创建nnblog用户并授权,创建users表,并添加部分数据。

//创建用户表
create table users(
       id number(10) primary key,
       name varchar2(50) not null,
       nickName varchar2(80) not null,
       password varchar2(50) not null,
       sex char(1) default '1',
       email varchar2(100)
);
alter table USERS add unique (NAME)

select * from users;

create sequence users_id start with 0 increment by 1 minvalue 0 maxvalue 99999999;

insert into users values(users_id.nextval,'admin','我是老大','admin','1','albert@qq.com');
insert into users values(users_id.nextval,'test','深情的维那斯','test','0','john@qq.com');
commit;

以上创建工作全部手写完成,源代码文件放入项目文件中。

###4,登录流程_增强

加入service(业务部分)、dao(数据访问部分)及任务4中的数据库访问工具类。 service、dao都必须基于接口、且进行专门的单元测试。

UserService				接口
UserServiceImpl			实现 
UserDao					接口
UserJdbcDaoImpl			实现
UserServiceImplTest
UserJdbcDaoImplTest

Dao负责访问数据库,并最终返回数据。注意返回的数据不能是ResultSet之类的java.sql中的类。一般返回的domain对象或者是集合、数组等。

Service负责业务逻辑。

####单元测试

所谓单元指的方法,也就是说,代码中所有的方法都有一个对应的测试方法;所有的类都要有一个对应的测试类。当然Servlet目前无法测试,在使用Spring框架之前,主要测试对象Service类中的方法和Dao类中的方法。

添加JUnit.jar依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

在测试方法上加上@Test注解。

###5,登录用户检查

引入过滤器的概念,并在项目中加入过滤器,以演示过滤器的实际作用。

1,编码转换过滤器 2,session验证过滤器

引入监听器的概念

1,完成用户重复登录,之前登录的用户被踢掉的功能。使用ServletContext类。

2,用户被踢掉时,给用户相应提示并且立即返回到登录页面。

完成一个用户登录时间记录,记录到数据库中,利用Filter完成。

1,建立online表,记录用户登录时间。

2,建立过滤器,在适当的位置过滤相关数据,存入数据库。

##任务二,注册流程

###1,创建相应的表结构

创建相应的数据库表,包括:用户详情表、爱好信息表、行政区划表

create table userDetail(
       id number(10) primary key,
       nativeplace_code varchar2(6) references nativePlace(code),
       hobby_code varchar2(50),
       userId number(10) references users(id)
);
create table hobby(
       id number(10) primary key,
       name varchar2(50),
       code number(2) unique
);
create sequence hobby_id start with 0 increment by 1 minvalue 0;

create table nativePlace(
       id number(10) primary key,
       name varchar2(50) unique,
       code varchar2(6)
);
alter table NATIVEPLACE add constraint unique1 unique (CODE);

###2,注册任务细化

1,编写用户注册页面,主要注册信息包括:用户名、昵称、密码、性别、爱好、来自于和Email。 2,在登录页面点击注册按钮,通过user.servlet?param=register转向注册页面。 3,在servlet中收集所需要的信息,包括:爱好信息,来自于的省级信息等。 4,在register.jsp页面中显示相关信息。 5,在省级下拉列表变化时,市级下拉列表显示相对应的信息。(利用ajax完成)

​ AJAX技术、ESM(ECMAScript Module)

6,提交form表单到服务器端 7,服务端根据提交信息写入数据库,完成用户注册。

###3,注册流程

graph LR(注册页面显示流程)
节点1(login.jsp)-->节点2(UserServlet)-->节点3(register.jsp)

graph LR(注册流程)
节点1(register.jps)-->节点2(UserServlet)-->节点3(InitServlet)-->节点4(login.jsp)

###4,相关知识点解析

1,在UserServlet中有两个注册相关的流程控制关键字:register、doRegister

​ register关键字是单纯的转向;doRegister是真正的注册操作。

​ 后面的的update和doUpdate关键字效果和这个一样。

2,存储转发和重定向的功能及区别

3,JSTL,Java自定义标签。自定义标签虽然像标签,但本质是一个Java类。

​ 引入自定义标签

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

4,${}指的是EL表代式。EL是用来在页面展示数据的一种编程语言。

5,原生AJAX的使用和封装技术。

6,JS模块化技术IIFE、CMD、AMD、ESM。这里只讲解了ESM技术(2018年5月之后的主流浏览器开始支持)。

##任务三,用户信息管理页面控制

完成用户信息管理页面的开发任务

###1,管理页面的任务细化

1,构建基础页面,显示用户信息。用户信息从users表、userDetail表及NativePlace表中获取。还要在Hobby表通过业务代码进行相应的转换处理。 ​ 利用List<Map<String,Object>>结构进行多表联合查询结果存储工作。 ​ 利用专门的业务代码替换原结构中的的编码为更友好的中文显示。

根本上是实现如下方法:

public List<Map<String, Object>> queryAll()

2,对表格进行适度的美化处理,增加删、改、查功能;增分页按钮功能。 4,完成删、改、查操作,每个一个操作都是一个完整的处理流程。注意改操作是两个流程。 5,完成分页功能的编写工作。 6,和主页连接。

返回并显示用户信息的具体解析:

1,实现三个表相互连接,具体的SQL语句如下:

select u.id,u.name,u.nickname,u.password,u.sex,u.email,np.name,ud.hobby_code
    from users u left outer join userdetail ud on u.id=ud.userid
    left outer join nativePlace np on ud.nativeplace_code=np.code;

2,List<Map<String,Object>>类型对应表数据的理解

3,将某行数据放入map中的具体写法:

for(int i=1,len=rs.getMetaData().getColumnCount();i<=len;i++){
	map.put(rs.getMetaData().getColumnName(i), rs.getObject(i));
}
//rs.getMetaData()方法获取rs中的元数据,其中包括了列数和每列的列名。
//rs.getMetaData().getColumnName(int index)方法返回第i列的列名(i从1开始计算),列名为大写

###2,提高任务

1,行政区划未选择时,显示列表显示红色的“未知”二字。 2,在显示列表中,行政区划一栏,改为省分,城市的写法。如:原来为“济南”,改为:“山东济南”。 3,考虑到用户起名方便,在数据库中加入昵称字段,用户名为英文、昵称字段可以录入中文信息。

###3,高难度任务解析

####1,显示爱好信息

在修改页中,每次自动显示爱好信息,并在已经选择的信息上打对号。

思路:在Hobby类中,加入一个表中没有的属性:private boolean selected,用以说明某个用户的选择。之后将Hobby表中的数据和用户数据中的hobby_code数据迭加,为用户选择了的数据,添加selected为真。显示时,把为真的数据显示为checked,就可以了。

####2,区域显示

修改页面中显示用户来自的区域,同时将用户已经选择的区域作为选中区域显示。

思路:与爱好类似,在NativePlace类中加入表没有的属性,以存储选择状态。然后在获得地区数据时,对数据进行比对。

具体的:

@Override
public List<NativePlace> setProvinceSelected(String code) {
    List<NativePlace> list=nativePlaceDao.getLevel1();
    String provinceCode=code.substring(0,2);
    list.stream().filter((item)->
             Objects.equals(item.getCode(),provinceCode)).forEach((item)->item.setSelected(true));
    return list;
}
@Override
public List<NativePlace> setCitySelected(String code) {
    List<NativePlace> list=nativePlaceDao.getLevel2(code.substring(0, 2));
    list.stream().filter((item)->
              Objects.equals(item.getCode(),code)).forEach((item)->item.setSelected(true));
    return list;
}

####3,分页流程的编码步骤

1,分页准备,了解Oracle数据库分页代码的原理,掌握Oracle数据库分页的编码方式。 2,创建Page类,封装分页相关数据。 3,创建分页方法,一般原型为:queryByPage(Page page); 4,初始页面分页 5,上、下页切换功能(主要难点在前端) 6,跳页功能的实现

####4,在分页的基础上实现即席查询

难点主要有两个:

实现多字段查询,这需要灵活的操作数据库,并根据查询字段的组合进行sql语句的拼装。大致的代码如下:

public void queryByPage(Page<List<Map<String, Object>>> page, UMQueryKeyword qk) {
    List<Object> params=new ArrayList<>();
    if(!Objects.equals("",qk.getName())) {
        params.add("%"+qk.getName()+"%");
    }
    if(!Objects.equals("",qk.getSex())) {
        params.add(qk.getSex());
    }	
    if(!Objects.equals("",qk.getHobbyCode())) {
        params.add("%"+qk.getHobbyCode()+"%");
    }
    params.add(page.getCurrentPage());
    params.add(page.getRowNumber());
    params.add(page.getCurrentPage());
    params.add(page.getRowNumber());
    String beginSQL="select * from ( select baseTable.*,rownum as rn from (";
    String SQL="select u.id,u.name,u.password,u.sex,u.email,np.name nativePlace_name,ud.hobby_code " + 
        "from users u left outer join Userdetail ud on u.id=ud.userid " + 
        "left outer join nativeplace np on ud.nativeplace_code=np.code where 1=1 ";
    if(!Objects.equals("",qk.getName())) {
        SQL+="and u.name like ? ";
    }
    if(!Objects.equals("",qk.getSex())) {
        SQL+="and u.sex=? ";
    }
    if(!Objects.equals("",qk.getHobbyCode())) {
        SQL+="and ud.hobby_code like ?";		
    }	
    String endSQL=" order by u.id) baseTable where rownum<=(?)*?) where rn>(?-1)*?";
    List<Map<String,Object>> list=JdbcTemplate.query(beginSQL+SQL+endSQL, (rs)->{
        List<Map<String,Object>> list0=new ArrayList<>();
        try {
            while(rs.next()) {
                Map<String,Object> map=new HashMap<>();
                for(int i=1,len=rs.getMetaData().getColumnCount();i<=len;i++){
                    map.put(rs.getMetaData().getColumnName(i), rs.getObject(i));
                }
                list0.add(map);
            }
        } catch (SQLException e) {
            log.debug("query by page method error,message is "+e.getMessage());
        }
        return list0;
    }, params.toArray());
    page.setPageData(list);
}

查询基础上的分页操作

主要的思路是把查询提交和分页提交合并,每次提交后都从后台获得查询数据并填入相应的位置。以保证分页时每次提交的数据除了currentPage外都相同。以下是JS中的核心分页代码。

function pagination(event){
	event.preventDefault();
	let nextPage=0;
	let currentPage=document.getElementById("queryCurrentPage").value;
	if(event.target.className=="btn_page"){
		switch(event.target.innerHTML){
			case "首页":nextPage=1;break;
			case "下一页":nextPage=Number.parseInt(currentPage)+1;break;
			case "上一页":nextPage=Number.parseInt(currentPage)-1;break;
			case "尾页":nextPage=document.getElementById("spanTotalPage").innerHTML;break;
		}
	}else if(event.target.id=="jumpPage"){
		nextPage=document.getElementById("jumpPage").value;
	}
	document.getElementById("queryCurrentPage").value=nextPage;
	document.getElementById("queryForm").submit();
}

####5,进一步的思考提高

能不能在分页代码中抽象出可以应用在所有查询中的公共分页模块。有余力的同学可以进行思考这个问题,并尝试着做一下。

##任务四,文章类型菜单任务

完成主页面左侧,文章分类菜单设计

###1,文章分类菜单数据表设计

设计数据表,数据表的设计核心是parentId,只有有了parentId才能出现父子节点。

create table articleType 
(
   id               number(10)           not null,
   typeName          varchar2(50),		
   parentId           number(10),		--为0为父节点,为id时为子节点,id为父节点的id
   url				varchar2(200),
   remark            varchar2(100),
   constraint PK_ARTICLETYPE primary key (id)
);

###2,获取分类数据

1,在服务器中分别获取父节点集和子节点集合。

2,在页面复用<c:forEach>完成父节点循环,在循环内部启动子循环,遍历子节点,显示的子节点,必须符合公式:subArticleType.parentId==parentArticleType.id。这样,每个父节点,都可以遍历出相应的子节点。

<ul id="leftMenu">
	<c:forEach items="${requestScope.parentTypes}" var="articleType">
		<li class="leftMenuLi1">${articleType.name}
		<div class="leftMenuLi1_image"></div></li>
		<ul id="leftSubMenu">
			<c:forEach items="${requestScope.subTypes}" var="subArticleType">
				<c:if test="${subArticleType.parentId==articleType.id}">
				<li class="leftMenuLi2">
				<a class="navigate" href="${subArticleType.url}">${subArticleType.name}</a>
				</li>
				</c:if>
			</c:forEach>
		</ul>
	</c:forEach>
</ul>

###3,有关文章分类菜单的进一步思考

本项目中的文章分类菜单是两层结构,所以可以用双层循环来完成。考虑如果要构造一个三层、四尾、N层的结构,应该如何思考、如何编码?

大致的思路:节点中包含所有子节点的集合、递归。

返回一个List,其中的每个元素是一个ArticleType类型,而ArticleType类型中,又包含一个List集合,该集合是该类型的所有子类型的集合。

public class ArticleType {
	private int id;
	private String name;
	private int parentId;
	...
	private List<ArticleType> subArticleTypes=new ArrayList<>();	//存储该节点的子节点

为List集合添加数据:

public List<ArticleType> getAllType() {
    List<ArticleType> parentTypes=articleTypeDao.getParentType();	//获取父节点
    List<ArticleType> subTypes=articleTypeDao.getSubType();			//获取所有子点
    parentTypes.forEach((parentNode)->{
        setSubNode(parentNode,subTypes);
    });
    return parentTypes;
}
//核心功能,为每个父节点添加内部子节点
private void setSubNode(ArticleType parentNode,List<ArticleType> subTypes) {
    subTypes.stream()
        .filter((subNode)->subNode.getParentId()==parentNode.getId())
        .forEach((subNode)->{
            //setSubNode(subNode,subTypes);		//如果超过两级,则使用递归,可以实现无限极
            parentNode.getSubArticleTypes().add(subNode);
    	});
}

##任务五,文章相关模块任务

1,创建文章信息表

2,添加文章内容流程,要使用之前准备富文本编辑器。

此处由于涉及到userId和typeId,所以之前的部分内容可以需要更新。主要指的是如何获取userId。

3,按照图片要求,显示文章类型页面。(CSS美化)

文章显示页面需要有分页功能。

4,文章类型信息编辑页面

可以修改、新增、父类型、子类型,不需要实现删除功能。文章类型不能随便删除,或者只能在没有该类型的子类型及相应类型的文章的情况下才可以删除。

##任务六,用户权限管理模块任务

###RBAC模型和数据表设计

RBAC(Role-Based Access Control),基于角色的访问控制。根据复杂度,可分为RBAC0、RBAC1、RBAC2、RBAC3。本模块使用RBAC0。RBAC0模型中角色可以理解为把权限分组。

  • RBAC1模型,引入了角色组的概念。
  • RBAC2模型,对角色进行了相应的限制。如:互斥角色、优化级角色等。
  • RBAC3模型,是RBAC1和RBAC2的合集,既有角色组,也包括可以增加各种限制。

创建基于页面粒度的用户权限管理功能,将主页左侧“管理菜单”纳入用户权限管理的范围之内,只有授权用户才可以看到并操作相应的菜单项,非授权用户无法看到更无法操作相应的菜单项。菜单项中的每个子项对应一个页面。

该模块共涉及五张表,除了users表之外,还包括:角色表、权限表、用户角色表和权限角色表

该模块共涉及三个页面,分别是:用户信息管理页面(作为用户信息模块的一部分已经完成);角色信息管理页面;权限信息管理页面。

###权限控制功能

利用Filter在转向到views/main.jsp时,对用户名进行验证,并根据用户名筛选相应权限。核心代码如下:

--根据用户名获取该用户权限
select p.permission,p.url from users u left outer join userRole ur on u.id=ur.userId
    left outer join permissionRole pr on ur.roleid=pr.roleId
    left outer join permission p on pr.permissionId=p.id
    where u.name='admin';
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request =(HttpServletRequest)req;
    HttpSession session=request.getSession();
    if(session.getAttribute("name")!=null) {
        PermissionService permissionService=new PermissionServiceImpl();
        List<Permission> permissions=permissionService.
            getPermissions((String)session.getAttribute("name"));
        session.setAttribute("permissions", permissions);
    }
    chain.doFilter(req, response); 
}

###角色信息管理页面

###权限信息管理页面

空文件

简介

该项目是基于MVC的Java Web基础教学项目,完成于2018年9月,不涉及前端内容。 展开 收起
Java
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/ha_ha_ha/javaweb_teaching_project.git
git@gitee.com:ha_ha_ha/javaweb_teaching_project.git
ha_ha_ha
javaweb_teaching_project
Java Web教学项目
master

搜索帮助