JAVA-Web基础

JAVAWEB基础

安装Tomcat 9

下载适合自己电脑架构的版本然后解压

下载地址:https://tomcat.apache.org/download-90.cgi

报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
		   At least one of these environment variable is needed to run this program

​			未定义JAVA_HOME和JRE_HOME环境变量
​			运行此程序至少需要这些环境变量中的一个

解决方案:

https://blog.csdn.net/wxb141001yxx/article/details/96976380

因为我的环境变量是在path中写死的,我要修改tomcat的setclasspath.bat文件

添加JAVA_HOME和JRE_HOME的路径

	set JAVA_HOME= D:\java\jdk-11
    set JRE_HOME=D:\java\jdk-11

测试tomcat

运行startup.bat,访问http://localhost:8080/

能正常访问tomcat就是安装完成了


修改tomcat服务器默认端口

找到\conf\server.xml进行修改

比如把端口修改为8001

<Connector port="8081" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

修改后重启服务可以看到访问8081端口能正常显示欢迎页


发布一个网站

先模仿自带的网站结构

\webapps\ROOT下就是默认自带的网站

复制一份吧文件夹名字改为baicha然后分析里面都是什么

可以看到有一些静态资源、还有一个index.jsp的jsp文件,WEB-INF下存放的是web.xml(网站配置文件)

我们把自带的页面和静态资源删除,只留下WEB-INF文件夹,新建一个index.html(tomcat会去找文件名为index的文件)

html中文乱码使用设置字符编码为utf-8

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<h1>欢迎使用tomcat</h1>

重启tomcat服务器访问http://localhost:8080/baicha/

会自动找到index.html文件进行解析显示出我们编写的代码,欢迎使用tomcat

一个网站常见的结构

	-baicha :网站的目录名
		- WEB-INF
			-classes : java程序
			-lib:web应用所依赖的jar包
			-web.xml :网站配置文件
		- index.html 默认的首页
		- static :静态资源目录
            -css
            	-style.css
            -js
            -img
         -.....

安装maven

下载安装Maven

官网:https://maven.apache.org/

下载完成后解压到安装目录D:\maven-3.8.4

配置环境变量

  • M2_HOME maven目录下的bin目录
  • MAVEN_HOME maven的目录
  • 在系统的path中配置%MAVEN_HOME%\bin

配置完成后在cmd中执行mvn -version可以看到maven home等信息就是安装完成了

配置阿里云镜像

在D:\maven-3.8.4\conf下找到settings.xml

添加阿里云镜像配置

<!--默认镜像
<mirror>
  <id>maven-default-http-blocker</id>
  <mirrorOf>external:http:*</mirrorOf>
  <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
  <url>http://0.0.0.0/</url>
  <blocked>true</blocked>
</mirror>-->

<!--可以不注释上面的,直接添加即可-->
<!--阿里云镜像-->
<mirror>
    <id>nexus-aliyun</id>  
    <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>  
    <name>Nexus aliyun</name>  
    <url>http://maven.aliyun.com/nexus/content/groups/public</url> 
</mirror>

配置maven本地仓库

查看配置

  <!-- localRepository
	maven将使用本地存储库的路径来存储工件。
   | The path to the local repository maven will use to store artifacts.
   |默认会在用户目录下生成/.m2/repository来存放本地仓库文件
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->

修改maven仓库位置为D:\maven-3.8.4\maven-repo

D:\maven-3.8.4\maven-repo


maven在IDEA中的使用

新建maven模块,使用原型创建

设置maven的信息

创建后会自动导入依赖,需要等一会

把项目结构补全


配置项目tomcat

添加本地tomcat配置

设置tomcat服务器的文件位置并且配置项目工件

此处我把url设置为了/,端口号为默认8080

和应用程序上下文(就是你设置的这个工件的url/后面的访问路径)

项目工件把当前模块的war打包发布配置进去了

war模式:将WEB工程以包的形式上传到服务器 ;
war exploded模式:将WEB工程以当前文件夹的位置关系上传到服务器;

运行tomcat访问http://localhost:8080/ 就能显示出新建的web项目自带的index.jsp中的Hello World!


开始技术点学习了

Servlet

编写HelloServlet类,继承HttpServlet

public class HelloServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        PrintWriter writer = resp.getWriter(); //响应流        writer.print("Hello,Serlvet");  //向页面写入    }     @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doGet(req, resp);    }}

编写servlet映射

在web.xml中配置servlet

    <!--注册Servlet-->    <servlet>        <servlet-name>hello</servlet-name>        <servlet-class>Servlet.HelloServlet</servlet-class>    </servlet>    <!--Servlet的请求路径-->    <servlet-mapping>        <servlet-name>hello</servlet-name>        <url-pattern>/hello</url-pattern>    <!--Servlet请求路径可以映射多个-->        <url-pattern>/hello1</url-pattern>    </servlet-mapping>

还可以使用通配符设置

  <servlet-mapping>      <servlet-name>hello</servlet-name>      <url-pattern>/hello/*</url-pattern>  </servlet-mapping>

重启服务器访问http://localhost:8080/hello


ServletContext()对象

使用this.getServletContext()往servlet中注入属性

servletContext.setAttribute(“name”,“baicha”);

public class HelloServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        ServletContext servletContext = this.getServletContext();        servletContext.setAttribute("name","baicha");    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doGet(req, resp);    }}

注册servlet

<!--注册Servlet--><servlet>    <servlet-name>hello</servlet-name>    <servlet-class>Servlet.HelloServlet</servlet-class></servlet><!--Servlet的请求路径--><servlet-mapping>    <servlet-name>hello</servlet-name>    <url-pattern>/hello</url-pattern></servlet-mapping>

编写conServlet从servlet上下文中获取属性对象

@Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        ServletContext servletContext = this.getServletContext();        String name = (String) servletContext.getAttribute("name");        //设置响应字符编码和格式        resp.setCharacterEncoding("UTF-8");        resp.setContentType("text/html");        PrintWriter writer = resp.getWriter(); //响应流        writer.print("名字为"+name);  //向页面写入    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doGet(req, resp);    }

注册conServlet

<!--注册Servlet--><servlet>    <servlet-name>name</servlet-name>    <servlet-class>Servlet.conServlet</servlet-class></servlet><!--Servlet的请求路径--><servlet-mapping>    <servlet-name>name</servlet-name>    <url-pattern>/name</url-pattern></servlet-mapping>

重启服务器

直接访问/name是没有名称的,会直接显示为名字为null,需要先访问/hello才能存入servlet上下文才能取出来数据


转发与重定向区别


HttpServletResponse响应

文件下载

@Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {        // 1. 要获取下载文件的路径        String realPath = "";        System.out.println("下载文件的路径:"+realPath);        // 2. 下载的文件名是啥? lastIndexOf最后一个\\后面+1位置的就是文件名        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);        // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));        // 4. 获取下载文件的输入流        FileInputStream in = new FileInputStream(realPath);        // 5. 创建缓冲区        int len = 0;        byte[] buffer = new byte[1024];        // 6. 获取OutputStream对象        ServletOutputStream out = resp.getOutputStream();        // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!        while ((len=in.read(buffer))>0){            //OutputStream吧缓冲区输出到客户端            out.write(buffer,0,len);        }        //关闭资源        in.close();        out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doGet(req, resp);    }

重定向

编写sendServlet,重定向到helloServlet

public class sendServlet extends  HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp. sendRedirect("/hello");//重定向
    }
}

注册

<!--注册Servlet-->
<servlet>
    <servlet-name>send</servlet-name>
    <servlet-class>Servlet.sendServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
    <servlet-name>send</servlet-name>
    <url-pattern>/send</url-pattern>
</servlet-mapping>

重定向访问时候url地址会变化,转发时候只有页面有变化


HttpServletRequest请求

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器, HTTP请求中的所有信息会被封装到HttpServletRequest,通过HttpServletRequest的方法,获得客户端的所有信息;

获取前端传回的信息
        //获取单个参数 比如用户名密码等
        req.getParameter("");
		//获取多个参数 比如复选框参数,比如爱好
        req.getParameterValues("");

Cookie

一个cookie只能存一个信息,一个cookie最大4KB

浏览器只能存三百个cookie,一个页面最多20个cookie

public class cookieServlet extends HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //我浏览器是GBK编码的,根据情况设置
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");
        PrintWriter out = resp.getWriter();
        Cookie[] cookies = req.getCookies(); //获得浏览器响应的Cookie

        if (cookies!=null){
            out.write("上一次访问时间是:");
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("time")){
                    long t = Long.parseLong(cookie.getValue()); //吧string类型的时间戳转换为long
                    Date date = new Date(t);
                    //吧时间输出
                    out.write(date.toString());
                }
            }
        }else{
            out.write("第一次访问,无cooick");
        }
        //第一次没有cookie,但是只要访问就自动给客户端返回一个cookie
        Cookie time = new Cookie("time", System.currentTimeMillis() + "");//+""吧long自动转换为string
                //有效期为一天 设置后浏览器关闭也能继续存活
        time.setMaxAge(24*60*60);
        resp.addCookie(time);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

注册servlet

<!--注册Servlet-->
<servlet>
    <servlet-name>coo</servlet-name>
    <servlet-class>Servlet.cookieServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
    <servlet-name>coo</servlet-name>
    <url-pattern>/coo</url-pattern>
</servlet-mapping>

删除了自带的默认cooick之后访问就是没有cooick的

服务端给客户端了一个time

刷新页面能显示出上一次的访问时间,并且服务端吧当前访问时间给了客户端

Session

session是独占浏览器的,关闭浏览器session失效

创建session

HttpSession session = req.getSession();
session.setAttribute("name","baicha");
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //解决乱码问题
    req.setCharacterEncoding("UTF-8");
    resp.setCharacterEncoding("UTF-8");
    resp.setContentType("text/html;charset=utf-8");

    //得到Session
    HttpSession session = req.getSession();
    //给Session中存东西
    session.setAttribute("name","baicha");
    //获取Session的ID
    String sessionId = session.getId();

    //判断Session是不是新创建
    if (session.isNew()){
        resp.getWriter().write("session创建成功,ID:"+sessionId);
    }else {
        resp.getWriter().write("session以及在服务器中存在了,ID:"+sessionId);
    }
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req,resp);
}

创建person实体类,编写有参构造

public class person {
    int age;
    String name;

    public person(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

往session中存入引用类型数据

//给Session中存东西
session.setAttribute("name",new person(1,"we"));

session删除数据和注销session

//删除id为name的session数据
session.removeAttribute("name");
//手动注销Session
session.invalidate();

web.xml中配置session失效时间

<!--设置Session默认的失效时间-->
<session-config>
    <!--15分钟后Session自动失效,以分钟为单位-->
    <session-timeout>15</session-timeout>
</session-config>

JSP

HTML只给用户提供静态的数据
JSP页面中可以嵌入JAVA代码,为用户提供动态数据;

在JSP页面中;

只要是 JAVA代码就会原封不动的输出;

如果是HTML代码,就会被转换为:out.write("\r\n");来输出给前端

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello</title>
</head>
<body>
<%= new java.util.Date()%>

<%--jsp脚本片段--%>
<%
    //计算1+2+...+100--
    int sum = 0;
    for (int i = 1; i <=100 ; i++) {
        sum+=i;
    }
    out.println("<h1>Sum="+sum+"</h1>");
%>


<%--在代码嵌入HTML元素--%>
<%
    for (int i = 0; i < 5; i++) {
%>
<h1>Hello,World  <%=i%> </h1>
<%
    }
%>


<%!
    static {
        //会在第一次访问页面时候运行
        System.out.println("Loading Servlet!");
    }

    private int globalVar = 0;

    public void kuang(){
        System.out.println("进入了方法Kuang!");
    }
%>
</body>
</html>

页面效果

JSP内置对象

  • PageContext 存东西 保存的数据只在一个页面中有效
    • Request 存东西 保存的数据只在一次请求中有效,请求转发会携带这个数据
  • Response
  • Session 存东西 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
  • Application 【SerlvetContext】 存东西 保存的数据只在服务器中有效,从打开服务器到关闭服务器
  • config 【SerlvetConfig】
  • out
  • page ,不用了解
  • exception

JAVA Bean

JavaBean就是一个实体类做了数据库的ORM映射

JavaBeen必须要有一个无参构造,要对数据库中的字段进行映射切属性私有,属性必须有相对应的set/get方法

ORM :对象关系映射

- 表—>类
- 字段–>属性
- 行记录---->对象

比如有一个person数据表,其中有id、name、age的属性,与数据库对应进行编写class

public class Person {
    private int Id;
    private String Name;
    private int Age;

    public Person() {
    }

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public int getAge() {
        return Age;
    }

    public void setAge(int age) {
        Age = age;
    }

    @Override
    public String toString() {  //非必须
        return "Person{" +
                "Id=" + Id +
                ", Name='" + Name + '\'' +
                ", Age=" + Age +
                '}';
    }
}

MVC三层架构

M Model 主要负责业务处理,比如Service层和Dao层就是Model层的东西

V View 视图层 主要做展示用户数据,给用户提供页面的交互操作的

C Controller 接口控制层 其中有Servlet层,给视图层提供调用的接口并吧视图层返回回来的操作提交给Service业务层操作

过滤器

导入import javax.servlet.*;下的Filter包

过滤器能在serclet层之前过滤一些数据和请求,还能对乱码进行处理

编写servlet往页面输出文字(必定乱码)

public class ceshiServlet extends HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.getWriter().write("这里是测试Servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

注册

<!--注册Servlet-->
<servlet>
    <servlet-name>ceshi</servlet-name>
    <servlet-class>Servlet.ceshiServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
    <servlet-name>ceshi</servlet-name>
    <url-pattern>/ceshi</url-pattern>
</servlet-mapping>

访问查看页面

编写过滤器对字符集进行编码

public class FilterDemo implements Filter {

    @Override
    //初始化
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    //过滤
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html;charset=UTF-8");

        System.out.println("CharacterEncodingFilter执行前....");
        filterChain.doFilter(servletRequest,servletResponse); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
        System.out.println("CharacterEncodingFilter执行后....");
    }

    @Override
    //销毁
    public void destroy() {

    }
}

注册过滤器

<!--配置过滤器-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>Filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <!--任何请求,会经过这个过滤器-->
    <url-pattern>/*</url-pattern>
</filter-mapping>

重启项目查看页面

监听器

可以实现的监听器接口非常多,当前使用session监听器去监控当前在线人数

注意:
Listener配置信息必须在Filter和Servlet配置之前,Listener的初始化(ServletContentListener初始化)比Servlet和Filter都优先,而销毁比Servlet和Filter都慢。

编写监听器

public class SessionListener implements HttpSessionListener {
    //创建session监听: 看你的一举一动
    //一旦创建Session就会触发一次这个事件!
    public void sessionCreated(HttpSessionEvent se) {
        //从上下文对象分钟获得session
        ServletContext ctx = se.getSession().getServletContext();
        //打印session对象id
        System.out.println(se.getSession().getId());
        //获取对象中sessionKey为OnlineCount的值为多少
        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            //如果为null默认设置为1
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }
        //给session对象设置值
        ctx.setAttribute("OnlineCount",onlineCount);

    }


    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        //从上下文对象分钟获得session
        ServletContext ctx = se.getSession().getServletContext();

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            //如果为空就设置为0
            onlineCount = new Integer(0);
        }else {
            //如果不为空但是走了这个方法默认就是销毁session了,直接值减一
            int count = onlineCount.intValue();
            onlineCount = new Integer(count-1);
        }
        //设置session
        ctx.setAttribute("OnlineCount",onlineCount);
    }
}

注册监听器

<!--注册监听器-->
<listener>
    <listener-class>Listener.SessionListener</listener-class>
</listener>

编写测试servlet

public class ceshiServlet extends HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws  IOException {
        //防止出现直接访问此servlet会出现500等问题
        HttpSession session = req.getSession();

        ServletContext servletContext = req.getServletContext();
        int onlineCount = (int) servletContext.getAttribute("OnlineCount");
        System.out.println(onlineCount);
        PrintWriter writer = resp.getWriter(); //响应流
        writer.print("在线人数为"+onlineCount);  //向页面写入
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws  IOException {
        doGet(req,resp);
    }
}

再打开一个浏览器访问页面

成功实现记录在线人数功能

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值