JAVAWEB 系列文章目录
黑马B站视频JAVAWEB部分的知识范围、学习步骤-【思维导图知识范围】
文章目录
银诗一宿
伊州歌
[作者]王维
[朝代]唐代
清风明月苦相思,荡子从戎十载余。
征人去日殷勤嘱,归雁来时数附书。
主要功能及亮点
- SSM架构,oracle 数据库
基于B/S架构的微博系统主要用功能包括:用户登录退出、用户信息维护、微博发布、好友关注、发布提问等等。本系统结构如下:
(1)用户模块:
实现登录功能
实现用户登录的退出
实现用户注册
实现已注册用户信息的修改
(2)微博模块:
实现微博的发布、修改、查看功能;
实现微博操作用户可以查看个人微博、好友微博、收藏微博等信息、对微博点赞、转发、收藏、评论、删除等
(3)好友模块:
实现用户关注、关注数+1、粉丝数+1、取消关注、拉黑用户、私信搜索用户等等;
(4)海螺模块:
实现发布问题、回答问题、积分增加等
(5) 后台管理员模块
实现管理员登录
实现使用柱状图显示微博、用户、评、海螺、评论、回答等数据的统计结果
用户搜索、用户封禁
oracle
Oracle公司(甲骨文)是全球最大的信息管理软件及服务供应商,成立于1977年,总部位于美国加州Redwood shore,面向全球开放oracle认证。
Oracle开发的关系数据库产品因性能卓越而闻名,Oracle数据库产品为财富排行榜上的前1000家公司所采用,许多大型网站也选用了Oracle系统,是世界最好的数据库产品。此外,Oracle公司还开发其他应用程序和软件。同时,Oracle在英语里还是“神谕”的意思,意为“替神说话的”,寓指Oracle公司的发展目标和决心地位。
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
mysql创立于1996年,最初属于mysql AB公司,2008年被sun收购,sun在2009年被oracle收购,所以mysql是2009年成为oracle旗下产品的。
SSM
JAVA技术这么多,有一些过度的技术要不要学?就比如SSM。
SSM技术是JAVAWEB技术之后的后续技术。
SSM框架是spring、spring MVC 、和mybatis框架的整合,是标准的MVC模式。标准的SSM框架有四层,分别是dao层(mapper),service层,controller层和View层。
Spring是一个英文单名词、形容词、及物动词、不及物动词,作名词时翻译为“春天;弹簧;泉水;活力;跳跃,人名;(德)施普林;(英、芬、瑞典)斯普林”,作形容词时翻译为“春天的”,作及物动词时翻译
为“使跳起;使爆炸;突然提出;使弹开”,作不及物动词时翻译为“生长;涌出;跃出;裂开”。
错了,如果你百度到这个解释那就差太多了。
spring是一个开源的Java开发框架,它提供了一种全面的解决方案,用于构建企业级应用程序。Spring框架的设计理念是基于面向对象的编程思想和松耦合的架构原则,旨在简化Java应用程序的开发,并提供可扩展性和灵活性。
Spring框架的核心特性包括:
1、 控制反转(IoC):Spring通过控制反转将对象的创建和管理交给框架来完成,开发人员只需关注业务逻辑的实现。这种解耦的设计模式可以降低组件之间的耦合度,提高代码的可维护性和可测试性。
2、 依赖注入(DI):Spring通过依赖注入将组件之间的依赖关系注入到对象中,而不是硬编码在代码中。这样可以使得组件之间的关系更加灵活,并方便进行单元测试和模块化开发。
spring会自动的把JAR里的功能加到项目里,不管你用不用得上。过于灵活,导致spring的JAR包依赖成为了一个噩梦。
注意的是,这个是SSM为啥 要升级成springBoot的重大原因
如果用升级成使用maven ,不用springBoot 这种父pom 的办法,那么初学者 把一个项目的JAR的依赖整明白,怕是黄瓜菜都凉了。关公大老爷都可以把1000多个华雄杀一个来回了。:)
3、 面向切面编程(AOP)
Spring提供了面向切面编程的支持,可以将横切关注点(如事务管理、安全性等)从业务逻辑中分离出来,以提高代码的模块化和重用性。
spring成名之作。SSM的时候,你可以理解为事务的最方便的实现。
springBoot的时候,你可以理解为配置类的各种妙用。
4、 组件化开发:Spring鼓励使用组件化开发的方式,通过将应用程序划分为多个独立的模块(组件),来提高代码的可重用性和可维护性。同时,Spring提供了一些开箱即用的组件(如数据访问、Web开发、消息传递等),简化了开发过程。
Mybatis
M 一般指的是mybatis.
MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。
本文介绍的项目还使用JSP的技术。非前后端分离。
SpringMVC
先说一下传统的MVC
要注意的是,传统的MVC就是浏览器访问的是控制器,然后,再到View的。
springMVC 呢? 从原则图上并没有太多的新技术
只一点,他的controller 可以方便的得到spring的其它类。只此一条就足够。
当然了,springMVC 还解决了struts 1.0的controller 的线程 安全的问题。他用DispacherServlet 转发至Controller 来实现。
环境及工具:
要注意的是SSM的项目刚好处于maven 的推出之际,所以有一些的SSM用的是pom.xml 引入包的方式,而有一些则是用的JAR包的方式:
本系列环境
环境 | win11 |
---|---|
工具 | idea 2018 |
jdk | 1.8 |
数据库 | oracle 11g |
maven | 不用 |
项目导入方式 | 目录导入 |
数据库前端工具 | plsql-developer |
数据库前端工具:plsql-developer(navicat 也可以)
关于环境的重要性,直接看上面的《IDEA如何配置JAVAWEB项目–【唐诗300首】》
如果要使用oracle19C 版本,就替换相应的JAR包就好。ojdbc14.jar
下面给出oracle对应的jar 包版本。
Oracle 9i: | ojdbc14.jar | (oracle.jdbc.driver.OracleDriver) |
---|---|---|
Oracle 10g: | ojdbc14.jar | (oracle.jdbc.driver.OracleDriver) |
Oracle 11g Release 1: | ojdbc5.jar | (oracle.jdbc.OracleDriver) |
Oracle 11g Release 2: | ojdbc6.jar | (oracle.jdbc.OracleDriver) |
Oracle 12c Release 1: | ojdbc6.jar | (oracle.jdbc.OracleDriver) |
Oracle 12c Release 2: | ojdbc8.jar | (oracle.jdbc.OracleDriver) |
Oracle 18c: | ojdbc8.jar | (oracle.jdbc.OracleDriver) |
Oracle 19c: | ojdbc8.jar | (oracle.jdbc.OracleDriver) |
项目里可能要用到的技术
当然了,以下的知识都不太熟的,就多问问周围的同学
JAVA
Java
编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高性能、多线程和动态的语言。不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程,Java是功能完善的通用程序设计语言,可以用来开发可靠的、要求严格的应用程序。
当编辑并运行一个Java程序时,需要同时涉及到四种方面:(1)Java编程语言(2)Java类文件格式(3)Java虚拟机(4)Java应用程序接口。使用文字编辑软件或集成开发环境(Eclipse或MyEclipse)在Java源文件中定义不同的类,通过调用类(这些类实现Java
API)中的方法来访问资源系统,把源文件编译生成一种二进制中间码,存储在class文件中,然后再通过运行与操作系统平台环境相对应的Java虚拟机来运行class文件,执行编译产生的字节码,调用class文件中实现的方法来满足程序的Java
API调用。 Java应用程序用户界面开发包
Swing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。
工具包中所有的包都是以swing作为名称,例如javax.swing,javax.swing.event。
JSP
JSP是一种能实现动态网页的技术。Sun公司最先提倡发行,并由多家公司共同开发与完善的。JSP技术通俗来说其实就是在普通的网页HTML文件中首先加上Java程序段来实现具体功能,然后再根据需要添加JSP标记(tag)进行记录,这样二者结合就可以形成JSP文件。其功能特别强大,基本可以实现大多数动态网页所需要的各种效果。用JSP技术所开发的网页具有跨平台的特点,在不同的操作系统,例如Windows,Linux,Winxp等操作系统上都可以运行起来。在服务器端进行大部分复杂的程序操作和功能实现操作,而这些并不需要用户直接参与或操作,最后的结果通过网络传送给用户。这样就减轻了用户工作量的同时也减少了浏览器的负担。因为有些浏览器并不支持Java语言,然而这不影响功能操作的实现,同样能够登录JSP网页,达到预想效果。
Java server page(以下简称JSP)为servlet技术的简化。JSP的功用在于它实现了Html语法中以<%, %>形式的java扩张。但是,值得注意的是,因为JSP与Servlet均在服务器端运行,故而往往以HTML文本为主要形式呈现客户端面前,所以当有 需求时,客户端可以便捷地通过浏览器来实现浏览。当网页服务器(web)遇到访问JSP提出的要求时,需要进行以下两个步骤:首先执行程序段,后将结果与htlm返回,以便系统更好运行。至于为何要进行的Java代码段的插入操作,其主要目的在于进行数据库的连接、网页重定向等等,以满足网页动态实现所需的各类功能。
HTML
Html语言是一种脚本语言,是一种规范和标准,在所有的开发语言中,是较为简单易学的一种,它有很多标签,运用标签就可以实现很多静态页面效果。虽然html语言相对其他语言来说比较简单,但是他能够实现的功能却很强大,因此受到广大用户的热爱。他可以实现静态网页设计,是学习前端设计的一门基础性语言。Html的结构包括头和主体部分,是WWW的描述语言。
TOMCAT
Tomcat服务器是一个免费的应用服务器,他的封面设计以一个动物的素描为灵感,正是因为这个设计理念,所以该项目以一个英文的动物名字为项目名称。因为其免费又好用,功能强大,所以成为大多数程序员的首选。Tomcat是一个小型的,轻量级的软件产品,他在启动运行时占用非常少的内存资源和系统开销,扩展性能比较好,支持多种应用需求,如果一个开发员对某一项功能实现特别感兴趣,他就直接可以将此功能加入到其中。Tomcat可以独立运行,身为网站的服务器,可以加载动态网页。
上代码
项目访问路径:http://localhost:8080/weibo/register_index
建表SQL
create table ADMIN_USER_TAB
(
U_ID NUMBER not null,
U_NICKNAME VARCHAR2(20),
U_NAME VARCHAR2(20),
U_PWD VARCHAR2(20) not null,
U_EMAIL VARCHAR2(200),
U_SEX VARCHAR2(8) not null,
U_POSITION VARCHAR2(50),
U_IMAGES VARCHAR2(200),
U_SIGN VARCHAR2(200),
REGISTERTIME DATE,
PWD_QUESTION VARCHAR2(100),
PWD_ANSWER VARCHAR2(100),
INTEGRAL NUMBER default 0,
CONCH_INTEGRAL NUMBER default 0,
A_NUMBER NUMBER default 0,
F_NUMBER NUMBER default 0,
CO_NUMBER NUMBER default 0,
BLOG_NUMBER NUMBER default 0,
LASTLOGIN DATE,
U_BIRTHDAY VARCHAR2(50),
U_STATE NUMBER default 0
)
;
create table COLLECT_TAB
(
C_ID NUMBER not null,
M_ID NUMBER,
COLLECT_USER_ID NUMBER,
BE_COLLECT_ID NUMBER,
COLLECT_DATE DATE,
COLLECT_STATE NUMBER default 0
)
;
alter table COLLECT_TAB
add primary key (C_ID);
create table COMM_TAB
(
C_ID NUMBER not null,
M_ID NUMBER,
COMMENT_ID NUMBER,
BE_COMMENT_ID NUMBER,
C_DATE DATE,
C_BODY VARCHAR2(500),
C_LIKE NUMBER,
C_STATE NUMBER
)
;
alter table COMM_TAB
add primary key (C_ID);
create table CONCH_TAB
(
ID NUMBER not null,
USERID NUMBER,
ADOPTID NUMBER,
CNUMBER NUMBER,
CONCHBODY VARCHAR2(1000),
CONCHTIME DATE,
STATE NUMBER default 0
)
;
alter table CONCH_TAB
add primary key (ID);
create table FRIEND_TAB
(
F_ID NUMBER not null,
U_ID NUMBER,
F_ATTEN NUMBER,
STATE NUMBER default 0
)
;
alter table FRIEND_TAB
add primary key (F_ID);
create table INTEGRAL_TAB
(
I_ID NUMBER not null,
I_OPERATION VARCHAR2(50),
I_NUMBER VARCHAR2(50),
I_DESC VARCHAR2(100)
)
;
alter table INTEGRAL_TAB
add primary key (I_ID);
create table LIKE_TAB
(
LIKE_ID NUMBER not null,
WEIBO_ID NUMBER,
LIKE_USER_ID NUMBER,
BE_LIKE_ID NUMBER,
LIKE_DATE DATE
)
;
alter table LIKE_TAB
add primary key (LIKE_ID);
create table MESSAGE_TAB
(
ID NUMBER not null,
USER_A NUMBER,
USER_B NUMBER,
M_MESSAGE VARCHAR2(500),
M_DATE DATE,
STATE NUMBER default 0
)
;
alter table MESSAGE_TAB
add primary key (ID);
create table RECORD_TAB
(
R_ID NUMBER not null,
U_EMAIL VARCHAR2(50),
I_ID NUMBER,
R_DATE DATE
)
;
alter table RECORD_TAB
add primary key (R_ID);
create table TRANS_TAB
(
T_ID NUMBER not null,
M_ID NUMBER,
TRANS_USER_ID NUMBER,
BE_TRANS_USER_ID NUMBER,
TRANS_DATE DATE
)
;
alter table TRANS_TAB
add primary key (T_ID);
create table USER_TAB
(
U_ID NUMBER not null,
U_NICKNAME VARCHAR2(20),
U_NAME VARCHAR2(20),
U_PWD VARCHAR2(20) not null,
U_EMAIL VARCHAR2(200),
U_SEX VARCHAR2(8) not null,
U_POSITION VARCHAR2(50),
U_IMAGES VARCHAR2(200),
U_SIGN VARCHAR2(200),
REGISTERTIME DATE,
PWD_QUESTION VARCHAR2(100),
PWD_ANSWER VARCHAR2(100),
INTEGRAL NUMBER default 0,
CONCH_INTEGRAL NUMBER default 0,
A_NUMBER NUMBER default 0,
F_NUMBER NUMBER default 0,
CO_NUMBER NUMBER default 0,
BLOG_NUMBER NUMBER default 0,
LASTLOGIN DATE,
U_BIRTHDAY VARCHAR2(50),
U_STATE NUMBER default 0,
BAN_TIME DATE
)
;
alter table USER_TAB
add primary key (U_ID);
alter table USER_TAB
add unique (U_EMAIL);
create table WEIBO_TAB
(
M_ID NUMBER not null,
U_ID NUMBER,
M_TRANUM NUMBER default (0),
M_COMNUM NUMBER default (0),
M_COLNUM NUMBER default (0),
M_LIKE NUMBER default (0),
M_DATE DATE,
M_BODY VARCHAR2(500),
M_IMAGE VARCHAR2(200),
M_STATE NUMBER default 0,
M_TAG NUMBER default 0,
M_T_STATE NUMBER default 0
)
;
alter table WEIBO_TAB
add primary key (M_ID);
create sequence SEQ_COLLECT
minvalue 1
maxvalue 999999999999999999999999999
start with 101
increment by 1
cache 20;
create sequence SEQ_COMM
minvalue 1
maxvalue 999999999999999999999999999
start with 261
increment by 1
cache 20;
create sequence SEQ_FRIEND
minvalue 1
maxvalue 999999999999999999999999999
start with 181
increment by 1
cache 20;
create sequence SEQ_LIKE
minvalue 1
maxvalue 999999999999999999999999999
start with 261
increment by 1
cache 20;
create sequence SEQ_MESSAGE
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
cache 20;
create sequence SEQ_RECORD
minvalue 1
maxvalue 999999999999999999999999999
start with 861
increment by 1
cache 20;
create sequence SEQ_TRANS
minvalue 1
maxvalue 999999999999999999999999999
start with 261
increment by 1
cache 20;
create sequence SEQ_USER
minvalue 1
maxvalue 999999999999999999999999999
start with 101
increment by 1
cache 20;
create sequence SEQ_WEIBO
minvalue 1
maxvalue 999999999999999999999999999
start with 541
increment by 1
cache 20;
这里的JSP是通过映射 访问的。有些类似springboot 的thymeleaf 的技术。也类似于thinkphp的MVC 的方式。
package cn.itbaizhan.web.controller;
import java.io.File;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import cn.itbaizhan.common.bean.Conch;
import cn.itbaizhan.common.bean.User;
import cn.itbaizhan.common.bean.Weibo;
import cn.itbaizhan.common.bean.WeiboComm;
import cn.itbaizhan.common.exception.UserServiceException;
import cn.itbaizhan.common.exception.WeiboServiceException;
import cn.itbaizhan.common.util.CommPage;
import cn.itbaizhan.common.util.FaceFormat;
import cn.itbaizhan.common.util.PageBean;
import cn.itbaizhan.service.IUserService;
import cn.itbaizhan.service.IWeiboService;
/**
* 控制器
*/
@Controller
public class MainController {
private ModelAndView mav = new ModelAndView();
@Resource
private IUserService userService;
@Resource
private IWeiboService weiboService;
PageBean page = new PageBean();
CommPage commPage = new CommPage();
String conchOperation = null;
String skey = "";
/**
* 跳转至注册页面
* @return
*/
@RequestMapping("register_index") //跳转到登陆页面
public ModelAndView register(){
ModelAndView mav = new ModelAndView("register");
return mav;
}
/**
* 功能:实现注册功能,在emailServlet方法中已经对用户输入的邮箱地址做了验证
* 因此不必在该方法中做验证,直接调用service层中的register方法将用户信息保
* 存到数据库中
* @param user SpringMVC中如果参数的名称跟控制器方法参数中声明的类中的属
* 性对应,就可以自动实例
* @return
*/
@RequestMapping("register_action")
public ModelAndView registerUser(User user){
mav.clear();
try {
if(user.getSex().equals("1")){
//用户性别为男,修改初始化头像
user.setImages("face/boy.png");
}else if(user.getSex().equals("0")){
//用户性别为女时
user.setImages("face/gril.png");
}
userService.register(user);
mav.setViewName("register");
mav.addObject("msg", "注册成功");
} catch (UserServiceException e) {
mav.setViewName("register");
mav.addObject("msg", e.getMessage());
}
return mav;
}
/**
* 功能 : 判断用户输入的邮箱是否已被注册,使用邮箱作为用户的唯一标识
* 作为接受前端发来异步请求接受的方法,查询数据库中邮箱地址为
* 用户输入的email的用户,如果存在,就返回显示错误的图片和
* 邮箱已被注册的文字,如果该email不存在,则返回正确的图片和
* @param resp HttpServletResponse响应
* @param email 异步请求所携带的用户输入的邮箱
* @return
*/
@RequestMapping("RegisterServlet") //判断用户输入的邮箱是否已被注册
public ModelAndView emailServlet(HttpServletResponse resp,String email){
mav.clear();
try {
User user = userService.findUserByEmail(email);
resp.setContentType("text");
PrintWriter pw = null;
pw = resp.getWriter();
if(user==null){
pw.print("<img src='icon/ok.png' align='absmiddle'> ");
}else{
pw.print("<img src='icon/err.png' align='absmiddle'> <font color='red'>邮箱已被注册</font>");
}
pw.flush();
pw.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 功能:判断用户输入的验证码是否正确,前端采用ajax异步交互,接受发来的请求与session中保存的验证码
* 做比较,如果正确,返回显示正确的图片,如果错误,返回验证码有误的文字和错误的图片,使用ajax实现异步交
* 互,局部刷新
* @param yzm 验证码,在前端js中发来的异步请求所携带用户填写的验证码
*/
@RequestMapping("AuthCodeServlet") //局部刷新返回用户输入的验证码是否正确
public String authCodeServlet(HttpSession session,HttpServletResponse resp,String yzm){
mav.clear();
try {
String ac = (String) session.getAttribute("authCode");
resp.setContentType("text");
PrintWriter pw = resp.getWriter();
if(ac.equals(yzm)){
//验证码正确
pw.print("<img src='icon/ok.png' align='absmiddle'> ");
}else{
//验证码错误
pw.print("<img src='icon/err.png' align='absmiddle'> <font color='red'>验证码错误</font>");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 跳转至登陆页面
* @return
*/
@RequestMapping("weibo_index")
public String weibo_index(){
return "index";
}
/***
* 验证用户名和密码是否正确
* 判断sava是否为yes,将用户名和密码保存在cookie中
* 判断用户上次登陆时间与本次登陆是否在同一天,如果不是,则为用户增加积分,并保存增加积分的记录信息
* @param userid 用户输入的用户名
* @param password 用户输入的密码
* @param save 是否自动登陆
* @param session
* @return
*/
@RequestMapping("login_action")
public ModelAndView loginAction(String userid,String password,String save,HttpSession session,HttpServletResponse resp){
mav.clear();
try {
User loginUser = userService.login(userid, password);
session.setAttribute("loginUser", loginUser); //将登陆用户信息保存在session中
List<User> userTuiJian = weiboService.findUserTuiJian(loginUser.getId());
mav.addObject("tuijian", userTuiJian);
mav.setViewName("redirect:home_index");
mav.addObject("p",1);
if(save!=null){
Cookie emailCookie = new Cookie("weibo_email", userid);
emailCookie.setMaxAge(24*60*60*7); //设置cookie过期时间为7天
Cookie pwdCookie = new Cookie("weibo_password", password);
pwdCookie.setMaxAge(24*60*60*7);
resp.addCookie(pwdCookie);
resp.addCookie(emailCookie);
}
Map<String, Object> alerts = userService.alerts(loginUser.getId());
session.setAttribute("alerts", alerts);
} catch (UserServiceException | WeiboServiceException e) {
mav.setViewName("forward:register_index");
mav.addObject("msg", e.getMessage());
}
return mav;
}
/**
* 跳转至用户个人首页
*/
@RequestMapping("home_index")
public ModelAndView home_index(Integer p,HttpSession session){
mav.clear();
mav.setViewName("home");
if( p == null){
p = 1;
}
User user = (User)session.getAttribute("loginUser");
try {
int num = weiboService.findHomeWeiboNum(0); //微博页数
if(num%10 == 0){
page.setTotalPage(num/10);
}else{
page.setTotalPage(num/10+1);
}
page.setPage(p); //微博分页为第一页
page.setMinPage(p*10-9);
page.setMaxPage(p*10);
commPage.setPage(1); //评论分页
commPage.setMinPage(1);
commPage.setMaxPage(5);
List<Weibo> list = weiboService.findHomeWeibo(0, page, null);
list = FaceFormat.formt(list);
for(int i=0;i<list.size();i++){
long uId = list.get(i).getU_id(); //获取用户id
User weibo_user = userService.findUserById(uId);
list.get(i).setUser(weibo_user); //将user信息组装到weibo类中
boolean b = weiboService.userLikeWeibo(list.get(i).getId(), user.getId());
list.get(i).setB(b);
//重新查找未读私信数目
Map<String, Object> alerts = userService.alerts(user.getId());
session.setAttribute("alerts", alerts);
}
List<User> userTuiJian = weiboService.findUserTuiJian(user.getId());
mav.addObject("tuijian", userTuiJian);
mav.addObject("pageBean", page);
mav.addObject("weiboList", list);
} catch (Exception e) {
e.printStackTrace();
}
return mav;
}
/**
* 跳转至修改用户基本信息页面
*/
@RequestMapping("userinfo_index")
public ModelAndView userinfo_index(){
mav.clear();
mav.setViewName("user/userinfo");
return mav;
}
/**
* 功能:修改用户基本信息
* 获取用户输入的信息,将生日拼接为xxxx-xx-xx的格式
* 获取session中的登陆用户
* 修改session中用户的属性值
* 调用service层中修改用户
*/
@RequestMapping("userinfo_action")
public ModelAndView userinfo_action(HttpSession session,User user,String year,String month,String day){
mav.clear();
String birthday = year+"-"+month+"-"+day; //拼接生日
User loginUser = (User) session.getAttribute("loginUser"); //获取登陆用户
loginUser.setNickName(user.getNickName());
loginUser.setName(user.getName());
loginUser.setSex(user.getSex());
loginUser.setSign(user.getSign());
loginUser.setPosition(user.getPosition());
loginUser.setBirthday(birthday);
session.setAttribute("loginUser", loginUser);
try {
userService.updateUser(loginUser);
mav.addObject("msg", "修改成功!");
} catch (UserServiceException e) {
mav.addObject("msg", e.getMessage());
}
mav.setViewName("forward:userinfo_index");
return mav;
}
/**
* 跳转至用户密码页面
*/
@RequestMapping("pwd_index")
public String pwd_index(){
return "user/password";
}
/**
* 跳转至用户头像页面
*/
@RequestMapping("face_index")
public String face_index(){
return "user/face";
}
/**
* Ajax验证用户旧密码
*/
@RequestMapping("PWDServlet")
public String pwd(HttpSession session,HttpServletResponse resp,String pwd){
mav.clear();
try {
User user = (User) session.getAttribute("loginUser");
resp.setContentType("text");
PrintWriter pw = null;
pw = resp.getWriter();
if(user.getPassword().equals(pwd)){
pw.print("<img src='icon/ok.png' align='absmiddle'> ");
}else{
pw.print("<img src='icon/err.png' align='absmiddle'> <font color='red'>密码错误</font>");
}
pw.flush();
pw.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 保存用户新密码
*/
@RequestMapping("updatePwd")
public ModelAndView updatePwd(String newpwd,HttpSession session){
mav.clear();
mav.setViewName("user/password");
User user = (User)session.getAttribute("loginUser");
try {
user.setPassword(newpwd);
userService.updateUser(user);
session.setAttribute("loginUser", user);
mav.addObject("msg", "修改成功");
} catch (UserServiceException e) {
e.printStackTrace();
}
return mav;
}
/**
* 跳转至修改用户密保页面
*/
@RequestMapping("question_index")
public String question(){
return "user/question";
}
/**
* Ajax验证用户输入的密保问题是否正确
*/
@RequestMapping("QAServlet")
public String QAServlet(HttpSession session,String answer,HttpServletResponse resp){
mav.clear();
User user = (User)session.getAttribute("loginUser");
try {
resp.setContentType("text");
PrintWriter pw = resp.getWriter();
if(user.getPwdAnswer().equals(answer)){
pw.print("<img src='icon/ok.png' align='absmiddle'> ");
}else{
pw.print("<img src='icon/err.png' align='absmiddle'> <font color='red'>答案错误</font>");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 修改密保问题和答案
*/
@RequestMapping("updateQuestion")
public ModelAndView updateQuestion(HttpSession session,String newQuestion,String newAnswer){
mav.clear();
User user = (User)session.getAttribute("loginUser");
user.setPwdQuestion(newQuestion);
user.setPwdAnswer(newAnswer);
try {
userService.updateUser(user);
session.setAttribute("loginUser", user);
mav.setViewName("forward:question_index");
mav.addObject("msg", "修改成功!");
} catch (UserServiceException e) {
e.printStackTrace();
}
return mav;
}
/**
* 保存用户头像
*/
@RequestMapping("updateFace")
public ModelAndView updateFace(@RequestParam("icon") MultipartFile icon,HttpSession session,HttpServletRequest req){
mav.clear();
mav.setViewName("user/face");
User user = (User)session.getAttribute("loginUser");
if(!(icon.isEmpty())){ //如果文件存在,isEmpty文件为空
//保存文件目录
String path = req.getServletContext().getRealPath("/")+"WEB-INF/jsp/face/"+user.getId()+icon.getOriginalFilename();
File newFile = new File(path);
//判断文件目录存在不存在,如果不存在就创建目录
if(!(newFile.getParentFile().exists())){
newFile.getParentFile().mkdirs();
}
try {
icon.transferTo(newFile); //转存文件
File oldIcon = new File(req.getServletContext().getRealPath("/")+"WEB-INF/jsp/"+user.getImages()); //删除之前的头像
if(!(user.getImages().equals("face/boy.png") || user.getImages().equals("face/girl.png"))){
//先判断用户之前的头像不是系统默认的头像,然后删除用户之前的头像
if(oldIcon.exists()){
oldIcon.delete();
}
}
user.setImages("face/"+user.getId()+icon.getOriginalFilename());
userService.updateUser(user); //保存用户头像
session.setAttribute("loginUser", user); //将保存后的用户头像信息保存在用户session中
} catch (Exception e) {
e.printStackTrace();
}
}else{
mav.addObject("msg", "图片不存在");
}
return mav;
}
@RequestMapping("conch_index")
public ModelAndView conchIndex(HttpSession session,String operation,int nPage){
mav.clear();
mav.setViewName("user/conch");
User user = (User) session.getAttribute("loginUser");
if(operation != null){
conchOperation = operation;
}
try {
//海螺分页
//获取海螺总数
int num = userService.conchNum(user.getId(), conchOperation);
if(num%5 == 0){
if(num == 0){
page.setTotalPage(1);
}else{
page.setTotalPage(num/5);
}
}else{
page.setTotalPage(num/5+1);
}
page.setPage(nPage); //每5页一分页
page.setMinPage(nPage*5-4);
page.setMaxPage(nPage*5);
//查找海螺显示
Map<String, Object> map = userService.conchIndex(user.getId(), conchOperation ,page);
List<User> userTuiJian = weiboService.findUserTuiJian(user.getId());
mav.addObject("tuijian", userTuiJian);
mav.addObject("conch", map);
mav.addObject("pageBean", page);
} catch (Exception e) {
e.printStackTrace();
}
return mav;
}
@RequestMapping("publishConch")
public ModelAndView publishConch(HttpSession session,String inputbox,int cNumber){
mav.clear();
mav.setViewName("user/conch");
User user = (User) session.getAttribute("loginUser");
Conch conch = new Conch();
conch.setcNumber(cNumber);
conch.setConchBody(inputbox);
conch.setUserId(user.getId());
try {
userService.publishConch(conch);
mav.addObject("msg", "发布成功!");
//海螺分页
//获取海螺总数
int num = userService.conchNum(user.getId(), conchOperation);
if(num%5 == 0){
page.setTotalPage(num/5);
}else{
page.setTotalPage(num/5+1);
}
page.setPage(1); //每5页一分页
page.setMinPage(1*5-4);
page.setMaxPage(1*5);
//查找海螺显示
Map<String, Object> map = userService.conchIndex(user.getId(), conchOperation ,page);
List<User> userTuiJian = weiboService.findUserTuiJian(user.getId());
mav.addObject("tuijian", userTuiJian);
mav.addObject("conch", map);
mav.addObject("pageBean", page);
} catch (Exception e) {
e.printStackTrace();
}
return mav;
}
/**
* 海螺详细问题页面
* conchDetail?conchId=
* @return
*/
@RequestMapping("conchDetail")
public ModelAndView conchDetail(HttpSession session,long conchId){
mav.clear();
mav.setViewName("user/conchDetail");
User user = (User) session.getAttribute("loginUser");
try {
Map<String, Object> map = userService.conchDetail(conchId);
List<User> userTuiJian = weiboService.findUserTuiJian(user.getId());
mav.addObject("tuijian", userTuiJian);
mav.addObject("detailMap", map);
} catch (Exception e) {
e.printStackTrace();
}
return mav;
}
@RequestMapping("conchComm")
public ModelAndView createCommtoConch(long userId,long conchId,String inputbox){
mav.clear();
mav.setViewName("redirect:conchDetail");
WeiboComm comm = new WeiboComm(); //使用微博评论实体作为海螺评论实体
comm.setCommentId(userId);
comm.setWeiboId(conchId); //将微博id属性作为海螺id
comm.setCommentBody(inputbox);
try {
userService.conchComm(comm);
mav.addObject("conchId", conchId);
} catch (Exception e) {
e.printStackTrace();
}
return mav;
}
/**
* adoptComm?conchId=${detailMap.conch.id}&comm=${comm.id}
* @return
*/
@RequestMapping("adoptComm")
public ModelAndView adoptComm(long conchId,long comm){
mav.clear();
mav.setViewName("redirect:conchDetail");
try {
userService.adoptComm(conchId, comm);
} catch (UserServiceException e) {
e.printStackTrace();
}
mav.addObject("conchId", conchId);
return mav;
}
/**
* 搜索
*/
@RequestMapping("seach")
public ModelAndView seach(String key,String ac,int pag,HttpSession session){
mav.clear();
if(key != null){
skey = key;
}
User user = (User) session.getAttribute("loginUser");
if("weibo".equals(ac)){
mav.setViewName("seachWeiboPage");
}else if("user".equals(ac)){
mav.setViewName("seachUserPage");
}
try {
Map<String, Object> map = userService.seachWeiboAndUser(skey,pag,ac);
mav.addObject("map", map);
List<User> userTuiJian = weiboService.findUserTuiJian(user.getId());
mav.addObject("tuijian", userTuiJian);
} catch (Exception e) {
e.printStackTrace();
}
return mav;
}
@RequestMapping("forget")
public ModelAndView forget(String email){
mav.clear();
try {
User user = userService.findUserByEmail(email);
if(user == null){
//用户不存在的
mav.setViewName("register");
mav.addObject("msg", "该用户不存在!");
}else{
//用户存在
mav.setViewName("forget");
mav.addObject("fUser", user);
}
} catch (UserServiceException e) {
e.printStackTrace();
}
return mav;
}
@RequestMapping("forgetAnswer")
public ModelAndView forgetAnswer(String email,String answer,HttpServletResponse resp){
mav.clear();
try {
User user = userService.findUserByEmail(email);
resp.setContentType("text");
PrintWriter pw = resp.getWriter();
if(user.getPwdAnswer().equals(answer)){
pw.print("<img src='icon/ok.png' align='absmiddle'> ");
}else{
pw.print("<img src='icon/err.png' align='absmiddle'> <font color='red'>答案错误</font>");
}
pw.flush();
pw.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@RequestMapping("up_forget")
public ModelAndView up_forget(String email,User bUser){
mav.clear();
try {
User auser = userService.findUserByEmail(email);
if(auser.getPwdAnswer().equals(bUser.getPwdAnswer())){
//修改用户登陆密码
auser.setPassword(bUser.getPassword());
userService.updateUser(auser);
mav.setViewName("register");
mav.addObject("msg","密码重置成功!");
}else{
mav.setViewName("redirect:forget");
mav.addObject("email",email);
}
} catch (UserServiceException e) {
e.printStackTrace();
}
return mav;
}
@RequestMapping("exit")
public String exit(HttpSession session){
session.removeAttribute("loginUser");
session.removeAttribute("alerts");
return "register";
}
}
主页
项目访问路径:http://localhost:8080/weibo/register_index
地址是这个。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<c:if test="${msg!=null}">
<script type="text/javascript">
var msg="${msg}"
alert(msg);
</script>
</c:if>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<link rel="stylesheet" type="text/css" href="css/global.css" />
<link rel="stylesheet" type="text/css" href="css/friend.css" />
<title>搜索微博</title>
</head>
<body>
<!-- header开始-->
<%@include file="header.jsp" %>
<!-- header结束-->
<!-- container 开始-->
<table border="0" align="center" cellpadding="0" cellspacing="0" id="container" >
<tr>
<td width="670" height="600" valign="top">
<table border="0" align="center" cellpadding="5" cellspacing="0" id="guanzhu">
<tr>
<td>搜索到相关记录共${map.num}条</td><td align="right"></td>
</tr>
</table>
<table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" id="menu">
<tr>
<td width="33%" align="center"><table width="165" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td align="center"><a href="seach?ac=weibo&pag=1">微博</a></td>
<td align="center"><a href="seach?ac=user&pag=1">用户</a></td>
</tr>
</table></td>
<td width="18%" align="right"> </td>
<td width="49%" align="center">
<form id="form1" name="form1" method="post" action="seach?ac=weibo&pag=1">
<input name="key" type="text" class="input" id="textfield" placeholder="输入微博关键字。。。"/>
<input name="button" type="submit" class="btnsearch" id="button" value="搜索" />
</form></td>
</tr>
</table>
<!-- weibo 开始-->
<c:forEach items="${map.weibo}" var="weibo">
<table id="weibo" width="90%" border="0" align="center" cellpadding="3" cellspacing="0" style="background-color: #F8F8F8">
<tr>
<td rowspan="3" align="center" valign="top"><img src="${weibo.user.images}" width="50" height="50" /></td>
<td width="88%" class="content"><a href="user_index?userId=${weibo.user.id}">${weibo.user.nickName}</a><img src="icon/v.gif" width="11" height="10" align="middle" /><br> ${weibo.body}</td>
</tr>
<c:if test="${weibo.image != 'null'}">
<tr>
<td><img src="${weibo.image}" id="${weibo.id}" width="89" height="120" onclick="imgAct(${weibo.id})"/></td>
</tr>
</c:if>
<c:if test="${weibo.image == 'null'}">
<tr>
<td></td>
</tr>
</c:if>
<tr>
<td height="25"><table width="100%" border="0" cellpadding="0" cellspacing="0" id="weibo_status">
<tr>
<td>${weibo.str_pubTime}</td>
<td align="right">
<span id="like${weibo.id}" onclick="like(${weibo.id})" style="cursor:pointer">
<c:if test="${weibo.b==false}">赞(${weibo.likeN})</c:if>
<c:if test="${weibo.b==true}">已赞(${weibo.likeN})</c:if>
</span> |
<span id="trans${weibo.id}" onclick="trans(${weibo.id})" style="cursor:pointer">转发(${weibo.tranum})</span> |
<span id="comm${weibo.id}" onclick="comm(0,${weibo.id})" style="cursor:pointer">评论(${weibo.comnum})</span> |
<span id="coll${weibo.id}" onclick="coll(${weibo.id})" style="cursor:pointer">收藏</span>
</td>
</tr>
</table></td>
</tr>
<tr >
<td rowspan="3" align="center" valign="top" ></td>
<td style="width: 386px; ">
<!-- 评论开始 -->
<%@include file="comment.jsp" %>
<!-- 评论结束 -->
</td>
</tr>
<tr ></tr>
</table>
</c:forEach>
<table align="center" id="page">
<tr>
<td align="right">
<c:if test="${map.pageBean.page!=1}">
<a href="seach?ac=weibo&pag=${map.pageBean.page-1}" style="text-decoration:none">上一页</a>
</c:if>
第 ${map.pageBean.page} 页
<c:if test="${map.pageBean.page != map.pageBean.totalPage}">
<a href="seach?ac=weibo&pag=${map.pageBean.page+1}" style="text-decoration:none">下一页</a>
</c:if>
共 ${map.pageBean.totalPage} 页
</td>
</tr>
</table>
<!-- weibo 结束-->
</td>
<td width="280" align="center" valign="top" class="pageright">
<!-- userinfo 开始-->
<%@include file="userinfo.jsp" %>>
<!-- userinfo 结束--></td>
</tr>
</table>
<!-- container 结束-->
<!--footer开始-->
<%@include file="footer.jsp" %>
<!--footer结束-->
</body>
</html>
</html>
跑起来
访问如下的URL:
项目访问路径:http://localhost:8080/weibo/register_index
浏览器界面
项目里的细节也比较多,等到下一文里再讲解吧。
总结
提示:IT是一个要多动手的职业,一定要多练不要贪快:
SSM是一个历史上的辉煌一刻,是现在的springBoot 的基础,springBoot 其实,仅仅是把SSM的JAR包的问题简化了,oracle也是企业里使用比较多的数据库之一。只是安装包太大,安装之后占的内存较多,所以一直不太受初学者喜欢。
配套资源
SSM+oracle写个人博客项目–【唐诗300首】
https://download.csdn.net/download/dearmite/88202365