web开发:
在Java中,动态web资源开发的技术统称为JavaWeb
web应用程序:可以提供浏览器访问的程序
web应用程序编写完毕后,若想提供给外部访问;需要一个服务器来统一管理;
缺点
优点
ASP
服务器是一种被动操作,用来处理用户的一些请求和用户一些相应信息; IIS Tomcat
xml文件可以配置
访问网站:
关于maven父子工程的理解: 父项目中会有一个
<modules>
<module>servlet01</module>
</modules>
子项目中会有一个
<parent></parent>
父项目中的java子项目可以直接引用
编写一个servlet类,继承HttpServlet接口
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 响应流
PrintWriter writer = resp.getWriter();
writer.print("Hello,Servlet");
}
}
xml
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>com.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
Servlet是由web服务器调用,web服务器在收到浏览器请求之后,会:
一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
xml
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
一个Servlet可以指定通用映射路径------servlet优先级较高,会覆盖默认请求
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
xml
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<!--*前面不能加项目映射路径-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
默认请求路径------少用
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
web容器在启动的时候,他会为每个web程序都创建一个对应的ServletContext对象,他代表了当前的web应用;
servlet中保存的数据,在另外的servlet可以拿到。
ServletContext servletContext = this.getServletContext();
servletContext.setAttribute("userName", userName);
String userName = (String) servletContext.getAttribute("userName");
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
resp.getWriter().print(url);
// 该转发会带上d
this.getServletContext().getRequestDispatcher("/gp").forward(req,resp);
通过这张图你就可以看到,转发是在服务器之间进行的,它的意思虽然我没有你想要的资源但是我可以帮你找到,
重定向是告诉你,我Servlet1没有这个资源,但是我告诉你那里有,你自己通过浏览器去找,
maven由于他的约定大于配置,我们写的配置文件,可能无法被导出或者生效,解决方法
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
Properties 发现都被打包到了同一个路径下:classes,我们俗称为classpath 通过文件流读取。
webn服务器接收到客户端的http请求,针对请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse
用户登录
// 需要设置改项目的路径
resp.setHeader("Location", "/r/image");
resp.setStatus(HttpServletResponse.SC_FOUND);
resp.sendRedirect("/r/image");
重定向和转发区别? 相同点:
HttpServletRequest代表客户端的请求,用户通过http服务请求都被封装到Request下面。
java
req.getRequestDispatcher("/image").forward(req,resp);
会话:用户打开一个浏览器,点击了很多超链接,访问了多个web资源,关闭浏览器,这个过程称之为会话。 有状态会话:保存上次会话的状态 怎么证明自己是西电学生?
cookie
session
常见场景:网站登录之后,下次不需要登录
服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();
一个网站cookie是否存在上限
删除cookie;
什么是session:
session和cookie的区别:
session使用场景:
什么时候会被销毁? 话题:当浏览器关闭后,Session就销毁了吗? 答案:存在于浏览器上的唯一标识符JSESSIONID(sessionid)消失了,但是服务器中存放的sessionid并没有立马销毁。 分析:我们知道Session是JSP的九大内置对象(也叫隐含对象)中的一个,它的作用是可以保存当前用户的状态信息,初学它的时候,认为Session的生命周期是从打开一个浏览器窗口发送请求到关闭浏览器窗口,但其实这种说法是不正确的!当一个Session开始时,Servlet容器会创建一个HttpSession对象,那么在HttpSession对象中,可以存放用户状态的信息,Servlet容器为HttpSession对象分配一个唯一标识符即Sessionid,Servlet容器把Sessionid作为一种Cookie保存在客户端的浏览器 中用户每次发出Http请求时,Servlet容器会从HttpServletRequest对象中取出Sessionid,然后根据这个Sessionid找到相应的HttpSession对象,从而获取用户的状态信息。
其实让Session结束生命周期,有以下两种办法:
java server pages:java服务器端界面,也和servlet一样,用于动态web技术 最大的特点:
代码层面没有任何问题
服务器内部工作
tomcat中有一个work目录
IDEA中使用tomcat开发会在idea中生成一个work目录
浏览器向服务端发送请求,不管访问什么请求,其实都是在访问servlet
JSP最终会转换为java类
JSP本质还是一个servlet
java
final javax.servlet.jsp.PageContext pageContext; // 页面上下文
javax.servlet.http.HttpSession session = null; // session
final javax.servlet.ServletContext application; // applicationcontext
final javax.servlet.ServletConfig config; //配置
javax.servlet.jsp.JspWriter out = null; // out
final java.lang.Object page = this; // page当前页
输出页面前增加的代码
response.setContentType("text/html"); // 响应类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
如果是JAVA代码就会被原封不动的输出
如果是HTML代码就会被转换为out.write("
")这样的格式渲染到前端任何语言都有自己的语法,JPS作为java的一种应用,它拥有自己的扩充语法(了解即可),并且支持所有的java语法
<%--JSP表达式
作用:用来将程序的输出到客户端
<%= 变量或者表达式%>
--%>
<%= new java.util.Date()%>
JSP脚本片段
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
out.println("<h1>Sum=" + sum + "</h1>");
%>
<%--JSP脚本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
out.println("<h1>Sum=" + sum + "</h1>");
%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>Hello,World <%=i%></h1>
<%
}
%>
<%!
static {
System.out.println("Loading Servlet!");
}
private int g = 0;
public void test() {
System.out.println("in test method");
}
%>
<%@page%>
<%--g--%>
<%@include file=""%>
这个与上面的区别:下面的本质还是三个页面而上面是三个部分拼接成一个
jsp:include page="index.jsp"/
// 保存的数据只在一个页面有效
pageContext.setAttribute("name1", "1");
// 保存的数据只在一次请求中有效,请求转发(重定向无效)会携带这个数据
request.setAttribute("name2", "2");
// 保存的数据只在一次会话有效
session.setAttribute("name3", "3");
// 保存的数据只在服务器中有效,从打开服务器到关闭服务器
application.setAttribute("name4","4");
<!--JSTL表达式依赖-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL表达式:${}
JSP标签
<jsp:include page="index.jsp"/>
<%--转发--%>
<jsp:forward page="/jsptag2.jsp">
<jsp:param name="a" value="a"/>
<jsp:param name="b" value="b"/>
</jsp:forward>
JSTL标签
JSTL标签库的使用就是为了弥补HTML标签的不足;他自定义许多标签,可以供我们使用,标签的功能和java代码一样!
## 7、JavaBean
***
实体类
JavaBean有特点的写法:
* 必须定义无参构造
* 属性必须私有化
* 必须有对应的get/set方法
一般用来和数据库字段做映射ORM;
ORM:对象关系映射
* 表->类
* 字段->属性
* 行记录->对象
People表
| id | name | age | address |
| ---- | ---- | ---- | ------- |
| 1 | tom | 10 | 西安 |
| 2 | lin | 19 | 西安 |
| 3 | pet | 13 | 西安 |
```java
public class People {
private int id;
private String name;
private int age;
private String address;
}
<jsp:useBean id="people" class="com.entity.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="西安"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="3"/>
<jsp:setProperty name="people" property="name" value="tom"/>
<jsp:getProperty name="people" property="address"/>
<jsp:getProperty name="people" property="id"/>
<jsp:getProperty name="people" property="age"/>
<jsp:getProperty name="people" property="name"/>
什么是MVC:model view controller 模型、 视图、 控制器
servlet--CRUD--->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
Model
View
Controller(Servlet)
控制视图的跳转
登录----》接受用户的请求---》处理用户的请求(获取参数:username,password)----》交给业务层处理登录业务(判断用户名密码是否正确:事务)-----》Dao层查询用户名和密码是否正确----》数据库
Filter:过滤器,用来过滤网站的数据;
Filter开发步骤:
编写过滤器 ```java public class CharacterEncodingFilter implements Filter { // 初始化:web服务器启动就已经初始化了,随时等待监听 @Override public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init CharacterEncodingFilter");
}
// chain:链
/**
2.必须要让过滤器继续通行 */ @Override 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服务器关闭的时候,过滤器会销毁 @Override public void destroy() {
System.out.println("destroy CharacterEncodingFilter");
} }
3. 在web.xml中配置
```xml
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是/servlet的任何请求,都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
实现一个监听器的接口;(有n种)
重写方法
public class OnlineCountListener implements HttpSessionListener {
// 创建session监听,一旦创建一个session就会触发这个事件
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
if (onlineCount == null) {
onlineCount = new Integer(1);
} else {
int value = onlineCount.intValue();
onlineCount = new Integer(value + 1);
}
context.setAttribute("OnlineCount", onlineCount);
}
// 销毁session监听,一旦销毁一个session就会触发这个事件
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
if (onlineCount == null) {
onlineCount = new Integer(0);
} else {
int value = onlineCount.intValue();
onlineCount = new Integer(value - 1);
}
context.setAttribute("OnlineCount", onlineCount);
}
}
xml
<!--注册监听器-->
<listener>
<listener-class>com.listener.OnlineCountListener</listener-class>
</listener>
用户登陆之后才能进入主页!用户注销就不能进入主页!
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 转换过来才能过去session
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
if (httpServletRequest.getSession().getAttribute("USER_SESSION") == null) {
httpServletResponse.sendRedirect("/f/error.jsp");
}
chain.doFilter(request,response);
}
什么是JDBC:Java连接数据库
导入驱动
<!--连接数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
java语句
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
// 想数据库发送SQL的对象Statement:CRUD
Statement statement = connection.createStatement();
// 编写SQL
String sql = "select * from users";
// 执行SQL,返回结果集
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println("id" + resultSet.getObject("id"));
}
resultSet.close();
connection.close();
statement.close();
事务 要么都成功,要么都失败! ACID原则:保证数据的安全
开启事务
事务提交 commit
事务回滚 rollback
关闭事务