6 Star 18 Fork 57

Albert / Java Web教学项目

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

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); 
}

角色信息管理页面

权限信息管理页面

###test

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

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

发行版

暂无发行版

贡献者

全部

近期动态

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

搜索帮助