原理
MVC——M(Javabean)+V(jsp)+C(servlet)
开发步骤
项目准备:
1、Maven项目 -> webapp项目
2、在main下新建两个文件夹,java 、 resources 文件夹。
3、modules配置两文件夹类型。
开发代码:
1、引入支持jar pom -> javax.servlet-api(注意版本正确才可以使用注解)
2、UserServlet extends HttpServlet
3、编写servlet
4、配置tomcat - 启动tomcat
第一步
1. 新建maven项目
File → New → Project → Maven →
Create from archetype 前的复选框~不打钩,则创建的是一个空的maven工程 /
打钩,并选择 org.apache.maven.archetypes: maven-archetype-quickstart (快速开启模式)~适用于普通的java工程等
打钩,并选择org.apache.maven.archetypes:maven-archetype-webapp (创建的是javaWeb工程)
→ 填一下项目名、项目位置 → 然后再配置一下maven的:
Maven home path:配置maven的安装路径;
User settings file: maven的配置文件;
Local repository:本地仓库位置;
ps: IDEA的每个maven项目,每次都要重复配置Maven =>解决:IDEA中全局默认配置中去配置maven
——全局配置maven:File → New Projects Settings → Settings for New Projects →搜索框搜Maven → 配置maven的安装路径、配置文件路径、本地仓库路径
■ 安装目录 Maven home directory
■ maven的配置 User settings file
■ 本地仓库 Local repository
注意:
- 新建maven项目
- 勾选 create from archetype,则选择所建项目内容;不勾选则建立空项目
- 此时建立webapp,选择如图
建立留言功能项目,message
此处不需要填写,idea自带maven,如果此处需要填写需自行安装
注意保证网络畅通,因为需要下载本地库(官网)的jar包
2. 完善结构
与模板所给的结构不同
文件夹
更改版本:
安装的jdk13,需要自己更改
注意:
改变文件夹类型
- 在新建文件夹时选择
- 右键要更改的文件夹
- file→project structure
包package
java文件夹(=javabean):
新建package——entity、Dao、servlet
3. 依赖管理,更新pom
首先,原有模板引入了junit(测试),不用可以去掉
引入:
- 当有不存在的jar时输入内容会标红,此时可以点击右上角出现的标志下载相关jar包
<dependencies>
<!-- jsp-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- jdbc-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- jstl-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
引入失败not found
Could not find artifact xxx:xxx:pom: in nexus-aliyun
IDEA使用Maven工具导入servlet-api包后,编译项目时仍提示找不到javax.servlet.http包的原因及解决方案
第二步 BaseDao 📕
BaseDao.java
package Dao;
//使用BaseDao(优化JDBC),泛型、反射,无连接池,包含公共DQL、DML
import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseDao<T> {
//CRUD操作代码
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/text?useSSL=false";
String name = "root";
String pass = "123456";
// private static DataSource dataSource = new ComboPooledDataSource();
Class<T> clazz;
//反射获得clazz
@SuppressWarnings("unchecked")
public BaseDao() {
clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Connection getConnection(){
Connection connection = null;
try {
// //注册驱动 (仅仅做一次)
Class.forName(driver);
// //建立连接(Connection)
connection = DriverManager.getConnection(url, name, pass);
// connection = dataSource.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
//DQL
public void closeAll(ResultSet resultSet, Statement statement, Connection connection){
//释放资源(conn、statement、rs)
try {
if(resultSet != null){
resultSet.close();
}
if(statement != null){
statement.close();
}
if(connection != null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//DML
public void closeAll(Statement statement, Connection connection){
//释放资源(conn、statement、rs)
try {
if(statement != null){
statement.close();
}
if(connection != null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public int excuteUpdate(String sql,Object... objects) {
Connection connection = null;
PreparedStatement statement = null;
int ret = -1;
try {
connection = getConnection();
//创建运行SQL的语句(Statement)
statement = connection.prepareStatement(sql);
for (int i = 0; i < objects.length; i++) {
statement.setObject(i+1, objects[i]);
}
//运行语句
ret = statement.executeUpdate();
System.out.println(ret);
//处理运行结果(ResultSet)
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(statement,connection);
}
return ret;
}
//执行预编译DQL语句
public List<T> executeQuery(String sql, Object... param) {
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
List<T> list = new ArrayList<T>();
try {
conn = getConnection();
stat = conn.prepareStatement(sql);
if (param != null) {
for (int i = 0; i < param.length; i++) {
stat.setObject(i + 1, param[i]);
}
}
rs = stat.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columuCount = rsmd.getColumnCount();
while (rs.next()) {
T t = (T) clazz.newInstance();
for (int i = 0; i < columuCount; i++) {
Field f = clazz.getDeclaredField(rsmd.getColumnName(i + 1));
f.setAccessible(true);
f.set(t, rs.getObject(i + 1));
}
list.add(t);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(rs,stat,conn);
}
return list;
}
}
MessageDao.java
package Dao;
import entity.Message;
import java.util.List;
public class MessageDao extends BaseDao<Message>{
public int insert(Message message){
return excuteUpdate( "insert into msgboard (author,msg) values (?,?)",message.getAuthor(),message.getMsg());
}
//分页查询 bypage limit
public List<Message> getMessageByPage(int start,int limit){
return executeQuery("select * from msgboard limit ?,?",start,limit);
}
}
Message.java
package entity;
import java.util.Date;
public class Message {
// 私有属性
private int id;
private String author;
private String msg;
private Date date;
//重写toString(),显示输出内容
@Override
public String toString() {
return "Message{" +
"id=" + id +
", author='" + author + '\'' +
", msg='" + msg + '\'' +
", date=" + date +
'}';
}
//setter&getter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
Text.java
使用java应用程序来打印数据
import Dao.MessageDao;
import entity.Message;
public class Text {
public static void main(String[] args) {
MessageDao messageDao = new MessageDao();
Message message=new Message();
// 插入
// message.setAuthor("alixy");
// message.setMsg("bob");
// // messageDao.insert(message);
// System.out.println(messageDao.insert(message));
// 分页查询
messageDao.getMessageByPage(0,3).forEach(System.out::println);//注意maven1.8才可以使用
}
}
测试代码正确可以删除text,编写servlet
第三步 servlet
1. 新建servlet
详解idea文件右键创建New没有Create New Servlet的解决办法
= >生成
有两种方式doPosr()和doGet()
2.代码
tomcat配置、启用
- 配置Tomcat:
点击IDEA中的Add Configuration,或者打开菜单Run --> 选择Edit Configuration 都可以。
弹出窗口后点击+,然后往下滑,然后选择Tomcat Server的Local(如果没有Tomcat Server则点击 items more)。
- 删除虚拟路径,保证网页中访问连接为删除虚拟路径,填入 / ,保证网页中访问连接为http://localhost:8080
- 热部署
使用servlet打印数据
package servlet;
import Dao.MessageDao;
import entity.Message;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/show")
public class MessageServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
MessageDao messageDao = new MessageDao();
messageDao.getMessageByPage(0,3).forEach(System.out::println); //分页查询
}
}
http://localhost:8080 → http://localhost:8080/show
结果:
第四步 servlet深入+JSP
(1) MessageServlet.java 📕
package servlet;
import Dao.MessageDao;
import entity.Message;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/show")
public class MessageServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* servlet - javabean → DB */
MessageDao messageDao = new MessageDao();
//messageDao.getMessageByPage(0,3).forEach(System.out::println); //打印过程不正确
List<Message> messageList=messageDao.getMessageByPage(0,3);
/* list → jsp
servlet → jsp(servlet)=转发
转发+request */
request.setAttribute("msgList",messageList);
request.getRequestDispatcher("message.jsp").forward(request,response);
}
}
(2) JSP
1. 在webapp文件夹中新建message.jsp
前端内容:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title>留言板</title>
<meta charset="UTF-8">
<style>
div {
margin: 0;
padding: 0;
font-size: 12px;
margin: 0 auto;
}
h3 {
text-align: center
}
#container {
width: 500px;
}
.article {
border: 1px solid #a6cbe7;
margin-top: 5px;
}
.author {
background-color: #0099FF;
width: 100%;
height: 24px;
line-height: 24px;
}
.content {
height: 40px;
padding: 10px;
}
.author span {
float: right;
padding-right: 10px;
}
.time {
border-top: solid 1px #a6cbe7;
}
.page {
text-align: right;
height: 30px;
line-height: 30px;
padding-right: 10px;
}
</style>
</head>
<body>
<div id="container">
<div><h3>留言板</h3></div>
<div>
用户:<input type="text" name="searchAuthor"> 留言:<input type="text" name="searchMsg"> <input id="search" type="button" value="搜索">
<div class="article"v-for="msg in msgs">
<div class="author">用户:{{msg.author}}<span>{{msg.id}}#</span></div>
<div class="content">{{msg.msg}}</div>
<div class="time page">发表于:{{msg.date}}</div>
</div>
</div>
<div class="page">
<span id="prePage">上一页</span> <span id="nextPage">下一页</span>
</div>
<br>
<div>
<form>
<div>
用户: <input type="text" name="author" value=""/>
</div>
<br>
<div>
留言: <textarea name="message" rows="5" cols="72"></textarea>
</div>
<div align="center"><input type="reset" value="清除"/> <input id="submit" type="button" value="发表"/></div>
</form>
</div>
</div>
</body>
</html>
2. jsp —— 脚本、小脚本
第二步中实现了控制台输出数据。这里完成了数据的页面输出。
调整:
3. JSP —— jstl + el
① 引入taglib
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- 补充:
el用于访问对象
作用域:
按 application -> session ->request ->page 查找,没有不输出。多个存在并想要固定输出时(user),可加(requestScope.user)前缀,则去固定作用域取值。
jstl的taglib标签:
② jstl
<c:forEach>——配置var-对象;items-集合;begin end-从x到 x;step-步数;varStatus-状态
等价于:
for (Message msg : list)
③ 引入el表达式
<%@ page isELIgnored="false" %>
④ el(类似vue的写法)
在MessageServlet.java中数存在request:
则items为
message.jsp 📕
<-- 使用传统模型后就不重要了
<%@ page import="java.util.List" %>
<%@ page import="entity.Message" %>
-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入taglib--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%--引入el表达式--%>
<%@ page isELIgnored="false" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title>留言板</title>
<meta charset="UTF-8">
<style>
div {
margin: 0;
padding: 0;
font-size: 12px;
margin: 0 auto;
}
h3 {
text-align: center
}
#container {
width: 500px;
}
.article {
border: 1px solid #a6cbe7;
margin-top: 5px;
}
.author {
background-color: #0099FF;
width: 100%;
height: 24px;
line-height: 24px;
}
.content {
height: 40px;
padding: 10px;
}
.author span {
float: right;
padding-right: 10px;
}
.time {
border-top: solid 1px #a6cbe7;
}
.page {
text-align: right;
height: 30px;
line-height: 30px;
padding-right: 10px;
}
</style>
</head>
<body>
<div id="container">
<div><h3>留言板</h3></div>
<%-- 1. 脚本 (已经被代替) --%>
<%-- <%request.getAttribute("msgList");%>--%>
<%-- 从msgList取出List,attribute返回object对象(同集合),
存的时候向 上转型成object,取得时候需要把object向下转型成List--%>
<%-- 2. 小脚本 Java写法,强转 --%>
<%--<%List<Message> list =(List) request.getAttribute("msgList");%>
<%for(int i=0 ; i< list.size() ; i++) {
out.print(list.get(i));
}%>--%>
<%-- 3. 小脚本 优化 --%>
<%--<%List<Message> list =(List) request.getAttribute("msgList");%>
<div>
用户:<input type="text" name="searchAuthor"> 留言:<input type="text" name="searchMsg"> <input id="search" type="button" value="搜索">
<%for(int i=0 ; i< list.size() ; i++){ %>
<div class="article">
<div class="author">用户:<%out.print(list.get(i).getAuthor());%><span>{{msg.id}}</span></div>
<div class="content"><%=%>(list.get(i).getAuthor());%></div>
<div class="time page">发表于:{{msg.date}}</div>
</div>
<%}%>
</div>--%>
<%-- 4. jstl+el --%>
<div>
用户:<input type="text" name="searchAuthor"> 留言:<input type="text" name="searchMsg"> <input id="search" type="button" value="搜索">
<c:forEach var="msg" items="${requestScope.msgList}">
<%--需要循环迭代的对象msg所在list集合。items存在作用域问题--%>
<div class="article">
<%--el表达式--%>
<div class="author">用户:${msg.author}<span>${msg.id}#</span></div>
<div class="content">${msg.msg}</div>
<div class="time page">发表于:${msg.date}</div>
</div>
</c:forEach>
</div>
<div class="page">
<span id="prePage">上一页</span> <span id="nextPage">下一页</span>
</div>
<br>
<div>
<form>
<div>
用户: <input type="text" name="author" value=""/>
</div>
<br>
<div>
留言: <textarea name="message" rows="5" cols="72"></textarea>
</div>
<div align="center"><input type="reset" value="清除"/> <input id="submit" type="button" value="发表"/></div>
</form>
</div>
</div>
</body>
</html>
结果