使用IDEA+Maven创建Servlet项目
一、javaweb环境配置
- jdk下载并安装,设置环境变量JAVA_HOME并加入系统路径;
- IDEA下载并安装;
- maven下载并解压,用于自动下载和管理项目依赖的jar包等;设置环境变量MAVEN_HOME并加入系统路径;(新版IDEA会内嵌该插件;)修改maven解压文件夹中的"/conf/settings.xml"文件,可以自行设置其本地仓库位置和增加镜像下载源;
- Tomcat下载并解压,用于运行本机服务器
二、maven模板项目创建
-
新建工程:
2.选择maven,勾选“Create from archetype",表明选择从远程仓库中的获取原型模板进行创建;选择适用于javaweb项目的选项;
-
设置工程属性:
Name:工程名称;Location:工程位置;自行设置;
Artifact Coordinates:工件坐标系,下面三个信息用于唯一定位一个项目; -
设置Maven属性:
默认使用内嵌的maven模块;可以勾选override,使用下载的maven文件夹及其配置文件和配置仓库进行替换;
Properties:从远程获取原型文件配置项目时使用的参数,默认包括两者的坐标系;由于远程仓库获取文件较多,网速较慢,可以添加一个参数,只获取原型中的内部核心文件,提升加载速度;
-
生成工作项目:
这种模板方法生成maven工程中,文件目录结构是缺少main/java和main/resources,以及test文件夹的。
可以使用非模板生成标准的maven工程;如下图,
-
补足目录结构:
打开项目结构:
选择Moudules,设置项目的源文件、资源和测试目录:
右击选择“new folder…"分别创建main\java、main\resources和src\test\java等目录;
分别右击新建的目录,标记为源文件、资源和测试目录: -
配置Tomcat服务器:
添加启动器配置:
选中Tomcat的local,进行配置:
添加服务器调用的项目;
然后设置映射访问路径Application Context;
成功配置后,点击启动服务器:
它会自动运行调用项目的index.jsp页面; -
认识Maven工程及相关工具:
-
认识pom文件
maven 项目的核心文件;
一个需要注意的可能出现的bug:
三、servlet项目
3.1 项目创建
-
单工程多项目模块:新建一个非模板的普通Maven工程;
-
重置工程目录:删除src文件夹,因为会将需求的新建项目作为工程主模块;
在pom.xml中添加jsp和servlet依赖:
-
添加新的项目子模块:右击项目的“new -> module",选择添加模板webapp并进行配置;
子项目模块可以使用父项目的java; -
更新web.xml使其最新,补足模块的目录结构;
-
编写servlet项目:
建包package、添加类、实现servlet接口的doget()和dopost();
-
注册servlet并添加映射:
编辑web.xml;
-
配置Tomcat启动该项目
3.2 servlet常用方法
3. 2.1 ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
-
使用servletContext共享数据:当前应用的所有servlet可以拿到保存着servletcontext中的数据;servlet之间可以通过servletcontext进行数据交互;
另一个servlet可以使用该共享属性:
-
使用servletContext获取初始化参数:
初始化参数可以通过servletcontext的相关方法获取; -
使用servletContext进行请求转发:
-
使用servletContext读取资源文件
先构造一个资源文件:在resources目录或者java目录下新建properties后缀文件;
项目生成后这些资源文件都会被打包到了同一个路径下:classes,我们俗称这个路径为classpath;
如果.properties文件在java目录下且其中包含:
username=root12312
password=zxczxczxc
ServletContext可以使用流进行读取:
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/zhu2change/TestServlet/db.properties");
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
3.2.2 HttpServletResponse
- 下载文件:
3.3 过滤器
Filter开发步骤:
- 导包:注意选择是servlet用的filter包;
- 编写过滤器:实现Filter接口,重写对应的方法即可;
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现!
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
//Chain : 链
/*
1. 过滤中的所有代码,在过滤特定请求的时候都会执行
2. 必须要让过滤器继续同行
chain.doFilter(request,response);
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter执行前....");
chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
System.out.println("CharacterEncodingFilter执行后....");
}
//销毁:web服务器关闭的时候,过滤器会销毁
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
- 在web.xml中配置 Filter;
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.kuang.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是 /servlet的任何请求,会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
<!--<url-pattern>/*</url-pattern>-->
<!-- 别偷懒写个 /* -->
</filter-mapping>
3.4 监听器
实现一个监听器的接口(有n种监听器):
编写一个监听器,就是实现监听器的接口;
- 导入依赖的jar包;
- 编写接口示例:
//统计网站在线人数 : 统计session
public class OnlineCountListener implements HttpSessionListener {
//创建session监听: 看你的一举一动
//一旦创建Session就会触发一次这个事件!
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁session监听
//一旦销毁Session就会触发一次这个事件!
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
/*
Session销毁:
1. 手动销毁 getSession().invalidate();
2. 自动销毁
*/
}
- web.xml中注册监听器;
<!--注册监听器-->
<listener>
<listener-class>com.kuang.listener.OnlineCountListener</listener-class>
</listener>
3.5 JDBC
- 导入数据库依赖:
java.sql
javax.sql
mysql-conneter-java… 连接驱动(必须要导入) - IDEA中连接数据库:
- JDBC 固定步骤:
加载驱动;
连接数据库,代表数据库;
向数据库发送SQL的对象Statement : CRUD;
编写SQL (根据业务,不同的SQL);
执行SQL;
关闭连接(先开的后关);
public class TestJdbc {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.向数据库发送SQL的对象Statement,PreparedStatement : CRUD
Statement statement = connection.createStatement();
//4.编写SQL
String sql = "select * from users";
//5.执行查询SQL,返回一个 ResultSet : 结果集
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("birthday="+rs.getObject("birthday"));
}
//6.关闭连接,释放资源(一定要做) 先开后关
rs.close();
statement.close();
connection.close();
}
}
事务特性:全部成功或失败,使用回滚事务;
@Test
public void test() {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";
Connection connection = null;
//1.加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库,代表数据库
connection = DriverManager.getConnection(url, username, password);
//3.通知数据库开启事务,false 开启
connection.setAutoCommit(false);
String sql = "update account set money = money-100 where name = 'A'";
connection.prepareStatement(sql).executeUpdate();
//制造错误
//int i = 1/0;
String sql2 = "update account set money = money+100 where name = 'B'";
connection.prepareStatement(sql2).executeUpdate();
connection.commit();//以上两条SQL都执行成功了,就提交事务!
System.out.println("success");
} catch (Exception e) {
try {
//如果出现异常,就通知数据库回滚事务
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}