SSM+oracle写个人博客项目--【唐诗300首】

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
jdk1.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">&nbsp;</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>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
                	<span id="trans${weibo.id}" onclick="trans(${weibo.id})" style="cursor:pointer">转发(${weibo.tranum})</span>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
                	<span id="comm${weibo.id}" onclick="comm(0,${weibo.id})" style="cursor:pointer">评论(${weibo.comnum})</span>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
                	<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>&nbsp; &nbsp;     
        	</c:if>&nbsp; ${map.pageBean.page} &nbsp;&nbsp;&nbsp;
        	<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> 
          	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ${map.pageBean.totalPage} &nbsp;</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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

项目花园范德彪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值