JavaWeb框架-SSH-真品与“赝品”?

2023-12-30 21:20
文章标签 java web 框架 ssh 赝品 真品

本文主要是介绍JavaWeb框架-SSH-真品与“赝品”?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

话说

前一篇博客介绍了SSH框架的整合,今天就用起来。

目标——仿照CSDN个人博客主页面,创造一个它的“双胞胎”

笔者一直想创建一个属于自己的网站,然后把毕生之所学都用在这个网站上,以后的以后,这就是自己的作品,没事就拿出来回味回味,把玩把玩。我虽不定闻名于世,但是我所建立的网站可以永久“基业长青”。

扯远了哈。各位读者,晚上好。这篇博客就是想仿照CSDN的个人博客主页面来写一个玩一下。当然,这个博客今天先发表,后期有变动,再一步步更新。

目录


1、最终效果图
2、整体布局
3、SSH框架搭建
4、核心代码
5、页面
6、总结
7、待完善…


开发环境:
IntelliJ IDEA(2017.2.5)
MySQL
Maven Web项目

1、最终效果图

真品:

这里写图片描述

“赝品”:

这里写图片描述

优化之路还长,嘻嘻。见笑了,诸位!

2、整体布局

这里写图片描述

这里写图片描述

3、SSH框架搭建

步骤和上一篇一样。这里不再赘述,仅罗列步骤。注意开启声明式事务的时候,要把默认的基于接口的代理变为基于类的代理,否则总报错:找不到bean。其实神马问题也木有。

1、pom.xml
2、struts.xml
3、spring.xml
4、web.xml
5、搞定!庆祝一下(小二,上菜!)

1、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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.hmc.ssh</groupId><artifactId>CSDN_blog</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>CSDN_blog Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--spring jar--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.1.RELEASE</version></dependency><!--spring web--><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.0.1.RELEASE</version></dependency><!-- Struts2 --><dependency><groupId>org.apache.struts</groupId><artifactId>struts2-core</artifactId><version>2.5.13</version></dependency><!--spring和struts2整合需要一个插件包--><dependency><groupId>org.apache.struts</groupId><artifactId>struts2-spring-plugin</artifactId><version>2.5.13</version></dependency><!--配置Hibernate--><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.2.12.Final</version></dependency><!--Mysql驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency><!--配置数据连接池--><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency><!--导入 ORM--><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>5.0.1.RELEASE</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>RELEASE</version></dependency><!--配置AOP--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.12</version></dependency><!--Spring Test--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.1.RELEASE</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>RELEASE</version></dependency><!--导入jstl--><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency></dependencies><build><finalName>CSDN_blog</finalName></build>
</project>

2、struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN""http://struts.apache.org/dtds/struts-2.5.dtd"><struts><!--配置struts使其识别bookAction这种默认bean名称--><constant name="struts.objectFactory" value="spring"/><!--DMI配置--><constant name="struts.enable.DynamicMethodInvocation" value="true"/><constant name="struts.devMode" value="true"/><package name="csdn" extends="struts-default"><global-allowed-methods>regex:.*</global-allowed-methods><action name="*_*" class="{1}Action" method="{2}"><result name="success">/WEB-INF/{1}/{2}.jsp</result><result name="redirectUrl" type="redirect">${url}</result></action></package><include file="example.xml"/><!-- Add packages here --></struts>

要是世界上的配置都这么简单就好了。

这个配置最核心的就是DMI——Dynamic Method Invocation
开启动态方法调用:
第一步:写好action _ 这里有一个迷人的笑脸,可惜无法显示;
第二步:配置常量,开启动态方法调用;
第三部:对全局方法用正则表达式全部放行。

第三步如果没有做,就会出现这样的情况:
一个页面可以访问,其他页面访问不了。注意配置的每个细节。

3、spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--开启spring 注解--><context:component-scan base-package="com.hmc.csdn"/><!--配置数据源--><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><!--配置url username password--><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost/meice_blog"/><property name="username" value="root"/><property name="password" value="119913"/><!--初始化连接池大小--><property name="initialSize" value="10"/></bean><!--配置sessionFactory--><bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"><!--属性注入dataSource--><property name="dataSource"  ref="dataSource"/><!--扫描加入注解的实体类(基于包)--><property name="packagesToScan"><array><value>com.hmc.csdn.modle</value></array></property><!--配置Hiberante其他属性--><property name="hibernateProperties"><!--2种方式多可以--><!--  <value>hibernate.dialect=org.hibernate.dialect.MySQLDialecthibernate.hbm2ddl.auto=updatehibernate.show_sql=true</value>--><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><prop key="hibernate.hbm2ddl.auto">update</prop><prop key="hibernate.show_sql">true</prop></props></property></bean><!--配置声明式事务--><bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory"/></bean><!--还要配置基于AOP的事务管理--><tx:advice id="txAdvice" transaction-manager="txManager"><tx:attributes><tx:method name="*"/></tx:attributes></tx:advice><aop:config><aop:pointcut id="allMethod" expression="execution(* com.hmc.csdn.dao.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="allMethod"/></aop:config><!--配置基于类的代理,如果不配置或者false,就是默认基于接口--><!--如果没有配置,总是报错,类似:expected to be of type 'com.hmc.csdn.dao.BlogDao'but was actually of type 'com.sun.proxy.$Proxy27'--><aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy></beans>

这里和上一篇博客相比,只增加了一点,那就是开启了基于类的代理。

 <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

所以,上一篇博客的问题,到此就乖乖被摆平啦。

4、web.xml

这个不要忘记配置。所有的一切,都要通过Web来展现。我们和客户的第一次产品交流。

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!--配置struts2过滤器--><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--配置Spring监听器--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--配置可以找到spring.xml--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:spring.xml</param-value></context-param></web-app>

5、搞定!庆祝一下(小二,上菜!)

4、核心代码

严格按照面向对象、面向接口、面向切面来设计。

1) model
2) dao
3) service
4) controller

1) model

Blog

package com.hmc.csdn.modle;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;/*** User:Meice* 2017/11/7*/
@Entity
public class Blog {private int blog_id;private String blog_title;private String blog_content;@Id@GenericGenerator(name = "myid",strategy = "native")@GeneratedValue(generator = "myid")public int getBlog_id() {return blog_id;}public void setBlog_id(int blog_id) {this.blog_id = blog_id;}public String getBlog_title() {return blog_title;}public void setBlog_title(String blog_title) {this.blog_title = blog_title;}public String getBlog_content() {return blog_content;}public void setBlog_content(String blog_content) {this.blog_content = blog_content;}@Overridepublic String toString() {return "Blog{" +"blog_id=" + blog_id +", blog_title='" + blog_title + '\'' +", blog_content='" + blog_content + '\'' +'}';}
}

这里为了看效果,先设置了几个简单的字段,后期还会不断完善。

2) dao

IBlogDao

package com.hmc.csdn.dao;import java.util.List;public interface IBlogDao {void save(Object obj);void del(int id);void update(Object obj);List<?>  list();Object listOne(int id);}

BlogDao

package com.hmc.csdn.dao;
import com.hmc.csdn.modle.Blog;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.awt.print.Book;
import java.util.List;/*** User:Meice* 2017/11/7*/
@Repository
public class BlogDao extends HibernateDaoSupport implements IBlogDao{//继承框架底层封装好的获取sesson的方法,就可以避免在通过sessionFactory获取session了@Resource(name = "sessionFactory")public void setSuperSessionFactory(SessionFactory sessionFactory) {super.setSessionFactory(sessionFactory);}/*** 新增*/public void save(Object obj) {getSessionFactory().getCurrentSession().save(obj);}/*** 删除*/public void del(int id) {System.out.println("删除方法,进来了....");/*getSessionFactory().getCurrentSession().delete(id);*/  // Integer not a  entity!//需要注意,Hibernate删除是直接删除对象,但是根据的是id?所以...需要这么操作.Blog blog = new Blog();blog.setBlog_id(id);getSessionFactory().getCurrentSession().delete(blog);}/*** 修改*/public void update(Object obj) {getSessionFactory().getCurrentSession().update(obj);}/*** 查询所有*/public List<?> list() {List<Blog> list =   getSessionFactory().getCurrentSession().createQuery("from Blog blog  order by blog.blog_id desc").list();return list;}/*** 查询单个对象*/public Object listOne(int id) {Blog blog =(Blog)  getSessionFactory().getCurrentSession().createQuery("from Blog where blog_id = ?").setParameter(0,id).uniqueResult();return blog;}/*** 定义获取分页总条目数count的方法*/public int countBlogs() {Long countLon =(Long) getSessionFactory().getCurrentSession().createQuery("select count(blog_id) from Blog").uniqueResult();int count =  countLon.intValue();return  count;}/*** 定义分页查询获取博客列表方法getBlogsPager*/public List<Blog> getBlogsPager(int offset,int pageSize) {List<Blog> blogs =    getSessionFactory().getCurrentSession().createQuery("from Blog blog  order by blog.blog_id desc").setFirstResult(offset).setMaxResults(pageSize).list();return  blogs;}/*** 运行结果类似:* Hibernate: select blog0_.blog_id as blog_id1_0_, blog0_.blog_content as blog_con2_0_, blog0_.blog_title* as blog_tit3_0_ from Blog blog0_ limit ?*/}

3) service

IBlogService

package com.hmc.csdn.service;import java.util.List;public interface IBlogService {void add(Object obj);void del(int id);void update(Object obj);List<?>  list();Object listOne(int id);
}

BlogService

package com.hmc.csdn.service;
import com.hmc.csdn.dao.BlogDao;
import com.hmc.csdn.modle.Blog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;/*** User:Meice* 2017/11/7*/
@Service
public class BlogService implements IBlogService {private BlogDao blogDao;@Resource(name = "blogDao")public void setBlogDao(BlogDao blogDao) {this.blogDao = blogDao;}/*** 发布博客*/public void add(Object obj) {blogDao.save(obj);}/*** 删除博客*/public void del(int id) {blogDao.del(id);}/*** 修改博客*/public void update(Object obj) {blogDao.update(obj);}/*** 博客列表* @return*/public List<?> list() {List<Blog> list =(List<Blog>)  blogDao.list();return  list;}/*** 单条博客列表*/public Object listOne(int id) {Blog blog =(Blog)   blogDao.listOne(id);return blog;}/*** 调用博客数目方法*/public int count() {int count =  blogDao.countBlogs();return  count;}/*** 调用分页查询数据方法*/public List<Blog> getBlogsByPager(int offset,int pageSize) {List<Blog> blogs = blogDao.getBlogsPager(offset,pageSize);return blogs;}
}

这里的困惑是:定义接口,需要高屋建瓴的能力,否则看得不长远,定义的接口就比较幼稚。

4) controller

blogAction

package com.hmc.csdn.controller;
import com.hmc.csdn.modle.Blog;
import com.hmc.csdn.service.BlogService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.List;/*** User:Meice* 2017/11/7*/@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring.xml")
@Controller(value = "blogAction")
public class blogAction implements ModelDriven<Blog> {private Blog blog;@Autowiredprivate BlogService blogService;/*** Struts接收参数的第一种方式* 因为没发实现2个ModelDriven*/private int pageIndex=1;//当前页private int count;//博客总条目数private int totalPage;//总页数private int offset;//偏移量,用于limitprivate  int pageSize=15;//每页显示条目private List<Blog> blogs ;//存放博客,这样就把分页整体作为blogAction的一个属性/*** 博客列表*/public String list() {count =  blogService.count();pageIndex =pageIndex;offset= (pageIndex-1)*pageSize;//执行方法List<Blog> blogs =(List<Blog>) blogService.getBlogsByPager(offset,pageSize);//传递值ActionContext.getContext().put("blogs",blogs);return "success";}/*** 跳转到发布博客界面*/public String add() {System.out.println("我是blogAction==> 进来了...");return "success";}/*** 执行发布博客操作*/public String doAdd() {//调用方法blogService.add(blog);//重新跳转到blog_list界面ActionContext.getContext().put("url","blog_doAdd");return "redirectUrl";}/*** 跳转到修改博客界面* @return*/public String update() {//调用方法Blog blogOne =(Blog)  blogService.listOne(blog.getBlog_id());//传递值ActionContext.getContext().put("blog",blogOne);return  "success";}/*** 执行修改操作*/public String doUpdate() {//调用修改方法blogService.update(blog);ActionContext.getContext().put("url","blog_list");return "redirectUrl";}/*** 删除博客*/public String del() {//执行方法blogService.del(blog.getBlog_id());ActionContext.getContext().put("url","blog_list");return "redirectUrl";}//这个很像单例的设计模式public Blog getModel() {if(blog == null) {blog = new Blog();}return blog;}public int getPageIndex() {return pageIndex;}public void setPageIndex(int pageIndex) {this.pageIndex = pageIndex;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public int getTotalPage() {totalPage = (int)Math.ceil((double)count/pageSize);return totalPage;}public void setTotalPage(int totalPage) {this.totalPage = totalPage;}public int getOffset() {offset = (pageIndex-1)*pageSize;return offset;}public void setOffset(int offset) {this.offset = offset;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}
}

这里增加了分页的属性。也在BlogDao中增加了分页查询及查询博客总条目数的方法。

这里笔者想不到更好的传参方式,已经实现了一个ModelDriven,其他参数就通过属性方式来传递。应该还有更加简洁的办法,后期发现在优化。

5、页面

暂时只是做了个主页面,还有类别管理、评论管理、回收站等模块,后续陆续实现。

list.jsp——显示博客列表
add.jsp——发布博客
update.jsp——编辑博客
现在阶段,都还很丑陋,稚气未脱的柑橘。后期逐一美化。欢迎评论斧正!

list.jsp——显示博客列表

<%--User: MeiceDate: 2017/11/7Time: 10:11
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html>
<head><title>Meice_blog</title><%--这里路径使用基于工程的绝对路径--%><link type="text/css" rel="stylesheet"  href="/CSDN_blog/css/blog.css"><style type="text/css"></style><script  src="/js/jquery-3.2.1.jar" type="text/javascript"></script><script type="text/javascript"></script>
</head><body><div id="toolbar"><h2 align="center" style="color: green">Meice_CSDN博客</h2></div><div id="blog_whole"><div id="blog_head"></div><div id="tabs_head"><h2 id="test"></h2><ul id="ul_tab"><li><span><a href="#">文章管理</a></span></li><li><span><a href="#">类别管理</a></span></li><li><span><a href="#">评论管理</a></span></li><li><span><a href="#">回收站</a></span></li><li><span style="background-color: #a1ee08"><a href="blog_add">写新文章</a></span></li></ul></div><div id="sel_div"><ul><li>类别:&nbsp;&nbsp;</li><li><select style="width: 80px;height: 25px " ><option selected="selected">全部</option><option>前言</option><option>Java</option></select></li><li>&nbsp;&nbsp;类型:&nbsp;&nbsp;</li><li><select style="width: 80px;height: 25px"><option selected="selected">全部</option><option>原创</option><option>转载</option><option>翻译</option></select></li></ul></div><div id="list_bog"><table width="98%" align="center" border="1"><caption></caption><thead><tr><th>序号</th><th>标题</th><th>状态</th><th>阅读</th><th>评论</th><th>评论权限</th><th>操作</th></tr></thead><tbody><c:forEach var="blogs" items="${blogs}"><tr><td align="center">${blogs.blog_id}</td><td>${blogs.blog_title}</td><td align="center">审核中</td><td></td><td align="center">0</td><td align="center"><a href="#">禁止评论</a></td><td align="center"><a href="blog_update?blog_id=${blogs.blog_id}">编辑</a> |<a href="#">置顶</a> |<a href="blog_del?blog_id=${blogs.blog_id}" onclick="return confirm('真的忍心删除么?')">删除</a> |<a href="#">分类</a> |</td></tr></c:forEach><tr><td colspan="7" align="center"><c:if test="${pageIndex>1}"><a href="blog_list?pageIndex=1">首页</a><a href="blog_list?pageIndex=${pageIndex-1}">上一页</a></c:if><c:forEach var="x" begin="${pageIndex}" end="${pageIndex+9}"><a href="blog_list?pageIndex=${x}">${x}</a></c:forEach><c:if test="${pageIndex<totalPage}"><a href="blog_list?pageIndex=${pageIndex+1}">下一页</a><a href="blog_list?pageIndex=${totalPage}">末页</a></c:if>${pageIndex}/${totalPage}</td></tr></tbody><tfoot></tfoot></table></div></div><div id="pub_info"></div><div></div><div></div></body>
</html>

add.jsp——发布博客

<%--User: MeiceDate: 2017/11/7Time: 16:22
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>
<html>
<head><title>Meice_发布博客</title>
</head>
<body><form action="blog_doAdd" method="post">标题:<input type="text" name="blog_title"><br/><textarea name="blog_content" cols="50" rows="10"></textarea><br/><input type="submit" value="发布"></form>
</body>
</html>

update.jsp——编辑博客

<%--User: MeiceDate: 2017/11/7Time: 17:21
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head><title>Meice_修改博客</title>
</head>
<body><form action="blog_doUpdate" method="post">标题:<input type="text" name="blog_title" value="${blog.blog_title}"><br/><textarea name="blog_content" cols="50" rows="10"  >${blog.blog_content}</textarea><br/><input type="submit" value="修改"></form></body>
</html>

6、总结


1、解决问题不重要,重要的是解决问题的思路可以复用。比如总是报错,找不到bean,这个时候,就要耐心分析;
不是配置流程有问题,就是哪里写错了。

2、文本域鼠标开始定位没有在开头,下一次实现定位开头,不用回删;

3、如果博客内容过长,数据库字段是Hibernate自动生成的varchar(255),会报错如下:

Data truncation: Data too long for column 'blog_content' at row 1

待处理;

4、为方便分页,笔者采用页面重定向,反复生成大量数据。发现一个很有意思的现象,那就是重定向访问过多,谷歌、火狐、360浏览器都会自动停止,只有IE还在那里傻乎乎的运行。所以一下生成了1000多条数据,不过也好,分页起来更有“浩瀚”之美!

5、设计接口的工作,有点像企业创始人,他们到达一定阶段,也许、大概、或者就是做类似设计接口之类的事吧。设计接口,要有高瞻远瞩的能力呢,否则定义的接口,不是不完善就是不好用。


7、待完善…

革命尚未成功,同志仍需努力!

小朋友们,下期再会!

这篇关于JavaWeb框架-SSH-真品与“赝品”?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/554041

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定