Web---演示Servlet的相关类、下载技术、线程问题、自定义404页面

简介: Servlet的其他相关类: ServletConfig – 代表Servlet的初始化配置参数。 ServletContext – 代表整个Web项目。 ServletRequest – 代表用户的请求。

Servlet的其他相关类:
ServletConfig – 代表Servlet的初始化配置参数。
ServletContext – 代表整个Web项目。
ServletRequest – 代表用户的请求。
ServletResponse – 代表用户的响应。
HttpSession – 代表用户的一次会话。
本篇博客演示:ServletConfig类 和 ServletContext 类(网页点击量统计,留言板和图片下载技术(其他类型文件类似))

ServletConfig:

它包含了Servlet的初始化参数。
它还与ServletContext对像关联。
方法:
getInitParameter //获取单个配置的参数
getInitParameterNames //获取所有配置的名称集合
getServletContext //获取ServletContext(代表本项目)对像

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>
  <servlet>
    <description>演示ServletConfig类的用法</description>
    <servlet-name>ConfigServletDemo</servlet-name>
    <servlet-class>cn.hncu.servlets.ConfigServletDemo</servlet-class>
    <init-param>
        <param-name>name</param-name>
        <param-value>jack</param-value>
    </init-param>
    <init-param>
        <param-name>age</param-name>
        <param-value>23</param-value>
    </init-param>

  </servlet>

  <servlet-mapping>
    <servlet-name>ConfigServletDemo</servlet-name>
    <url-pattern>/conf</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

index.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>

  <body>
    <h1>演示Servlet的相关类</h1>
    <a href="conf">演示ServletConfig类的用法</a>
  </body>
</html>

ConfigServletDemo.java

package cn.hncu.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ConfigServletDemo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");

        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");
        //Servlet初始化参数
        //在web.xml中给<init-param>标签中配置参数和值

        //读取Servlet初始化参数--法一--通过getServletConfig()获得conf对象--这种方法是死的
        ServletConfig conf = this.getServletConfig();
        String name = conf.getInitParameter("name");
        String age = conf.getInitParameter("age");
        out.print("法一: "+name+" , "+age+"</br>");
        out.print("<hr/>");

        //读取servlet初始化参数--法二--直接通过当前servlet类的getInitParameter()方法--这个方法还是死的
        String name2 =this.getInitParameter("name");
        String age2 = this.getInitParameter("age");
        out.print("法二: "+name2+" , "+age2+" </br>");
        out.print("<hr/>");

        //在不知道参数名字的情况下,去遍历
        //读取servlet初始化参数--法三--通过getServletConfig()或当前servlet类的getInitParameterNames()动态获取所有参数名
        ServletConfig conf2 = this.getServletConfig();
        Enumeration<String> en = conf2.getInitParameterNames();
        while(en.hasMoreElements()){
            String paramName = en.nextElement();
            String value = conf2.getInitParameter(paramName);
            out.print("法三: "+paramName+" , "+value+" </br>");
        }

        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }
}

演示结果:

小小的总结:

ServletConfig获取初始化参数:

<!-- 在Servlet的配置初始化参数 -->
  <init-param>
    <param-name>name</param-name>
    <param-value>jack</param-value>
  </init-param>

servletConfig.getInitParameter(“name”); //即可以获取name
对应的值jack

方法:
getInitParameter //获取单个配置的参数
getInitParameterNames //获取所有配置的名称集合

演示ServletContext类的用法–网页点击量1:

index.jsp:

<a href="count1">演示ServletContext类的用法--网页点击量1</a>

web.xml

 <servlet>
    <description>演示统计网页访问量</description>
    <servlet-name>ServletContextDemo</servlet-name>
    <servlet-class>cn.hncu.servlets.ServletContextDemo</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletContextDemo</servlet-name>
    <url-pattern>/count1</url-pattern>
  </servlet-mapping>    

ServletContextDemo.java:

package cn.hncu.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletContextDemo extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        ServletContext context = this.getServletContext();
        Integer count = (Integer) context.getAttribute("count");
        if(count==null){
            count=1;
        }else{
            count++;
        }
        getServletContext().setAttribute("count", count);
        out.print("网站访问量:"+getServletContext().getAttribute("count"));


        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

每一个web应用,拥有一个唯一的ServletContext,当应用启动时创建,当应用关闭时销毁。
ServletContext可用于在同一个Web项目中,共享资源。

演示结果:

刷新一次,访问量就增加1,这个不好。

演示ServletContext类的用法–网页点击量2

和网页一共用一个浏览量,因为在一个项目中!!!

index.jsp:

<a href="count2">演示ServletContext类的用法--网页点击量2</a><br/>

web.xml:

<servlet>
    <description>演示ServletConfig类的用法</description>
    <servlet-name>CountServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.CountServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>CountServlet</servlet-name>
    <url-pattern>/count2</url-pattern>
  </servlet-mapping>    

ServletContextDemo.java:

package cn.hncu.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletContextDemo extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        ServletContext context = this.getServletContext();
        Integer count = (Integer) context.getAttribute("count");
        if(count==null){
            count=1;
        }else{
            count++;
        }
        getServletContext().setAttribute("count", count);
        out.print("网站访问量:"+getServletContext().getAttribute("count"));


        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

演示结果:

演示ServletContext类的用法—留言板

index.jsp:

<a href="chat">演示ServletContext类的用法---留言板</a><br/>

web.xml:

<display-name></display-name>

  <context-param>
    <param-name>charset</param-name>
    <param-value>utf-8</param-value>
  </context-param>
    <servlet>
    <description>演示ServletConfig类的用法</description>
    <servlet-name>ChatServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.ChatServlet</servlet-class>
  </servlet>
   <servlet-mapping>
    <servlet-name>ChatServlet</servlet-name>
    <url-pattern>/chat</url-pattern>
  </servlet-mapping>    

ChatServlet.java

package cn.hncu.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ChatServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        //显示留言板
        //读取当前用户的留言
        //request.setCharacterEncoding("utf-8");
        //获取servletCOnttext的初始化参数。注意,用this.getInitParameter()获取到的是servlet的初始化参数。
        String charset = getServletContext().getInitParameter("charset");
        request.setCharacterEncoding(charset);

        //记得读取留言之前必须要获取留言者的ip
        String ip = request.getRemoteAddr();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        //用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
        String time = sdf.format(new Date());
        // format(Object obj)格式化一个对象以生成一个字符串。这等效于 
        //format(obj, new StringBuffer(), new FieldPosition(0)).toString(); 

        String msg = request.getParameter("msg");
        String msgs = (String) getServletContext().getAttribute("msgs");

        if(msg!=null && !msg.trim().equals("") ){
            //把msg放到servletContext当中
            if(msgs==null){
                msgs = time+"&nbsp;&nbsp;留言者:<br/>"+ip+": "+msg;
            }else{
                msgs = msgs+"<br/>"+time+"&nbsp;&nbsp;留言者:<br/>"+ip+" :"+msg;
            }
            getServletContext().setAttribute("msgs", msgs);
        }

        //留言板-设置大小~

        String div = "<div style='border:1px solid red;width:800px;height:400px;overfow:auto'>"+
                    msgs+" </div>";
        //overflow 设置或获取表明当内容超出对象高度或宽度时如何管理对象内容的值。 
        //auto:在必需时对象内容才会被裁切或显示滚动条;
        //scroll:总是显示滚动条。
        if(msgs!=null){
            out.print(div);
        }

        //当前用户的留言表单
        out.print("<hr/>");
        out.print("<hr/>");
        String form = "<form action='chat' method='post'>"+
                        "留言:<input type='text' name='msg'/>"+
                        "<input type='submit' value='提交'/>"+
                        "</form>";
        out.print(form);

        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

演示结果:

只要服务器没关,只要在这个网站的留言全部都会在这里的:

获取服务器目录中的绝对路径–遍历图片浏览

index.jsp:

<a href="showImgs">演示ServletContext类的用法---获取服务器目录中的绝对路径--图片浏览</a><br/>

web.xml:

<servlet>
    <description>演示ServletConfig类的用法-图片显示</description>
    <servlet-name>ShowImgsServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.ShowImgsServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ShowImgsServlet</servlet-name>
    <url-pattern>/showImgs</url-pattern>
  </servlet-mapping>    

ShowImgsServlet.java:

package cn.hncu.servlets;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ShowImgsServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        //获取服务器项目根目录下的imgs文件夹下的所有图片文件名
        String realPath = getServletContext().getRealPath("/imgs");//参数是:项目根目录下的imgs文件夹
        //上一句返回的是:资源的绝对路径,即带盘符的路径:D:\apache-tomcat-7.0.30\webapps\myServletDemo2\imgs
        //System.out.println(realPath);

        File file = new File(realPath);
        //防护一下 file.isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
        if(!file.exists() || !file.isDirectory() ){
            return;
        }

        String fileNames[] = file.list();//返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
        for(String fileName:fileNames){
            //例:<img width=200 height=200 src='img/a.jpg'/>
            String img = "<img width=200 height=200 src='imgs/"+fileName+"'/>";
            out.print(img);
        }


        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

演示结果:

中文的路径不能显示图片!

图片下载:

本来一开始火狐的文件名有乱码的,百度了一下,原来火狐和IE等其他浏览器不同,于是写了判断浏览器的类型:
request.getHeader(“User-Agent”)中有含有浏览器操作系统等信息。
解决了这个问题。

index.jsp:

 <a href="down">图片下载</a>

web.xml:

<servlet>
    <description>演示文件下载</description>
    <servlet-name>DownServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.DownServlet</servlet-class>
  </servlet>
<servlet-mapping>
    <servlet-name>DownServlet</servlet-name>
    <url-pattern>/down</url-pattern>
  </servlet-mapping>    

DownServlet.java:

package cn.hncu.servlets;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 演示文件下载
 * @author 陈浩翔
 *
 * 2016-7-22
 */
public class DownServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //设置响应头--内容接收程序--浏览器看到这个响应头,就会把它认为的下载程序打开
        //(如果识别迅雷那么就会自动打开迅雷,如果没有则会打开一个“文件另存为”的对话框)
        response.setContentType("application/force-download;charset=utf-8");

        //设置响应头--告诉浏览器:文件名+文件类型
        String fileName = "湖南欢迎你2swenjia名.jpg";//这个是用户下载时,自动填写的下载名字


        String agent = request.getHeader("User-Agent");
        System.out.println(agent);
        if(agent.indexOf("Mozilla")!=-1){//火狐浏览器
            response.setHeader("Content-Disposition", "attachment;filename="+ new String(fileName.getBytes("GB2312"),"ISO-8859-1"));
        }else{
            //解决中文乱码问题(只要用下面一句对文件名进行编码就行了)
            fileName = URLEncoder.encode(fileName, "utf-8");//使用指定的编码机制将字符串转换为 application/x-www-form-urlencoded 格式。
            response.setHeader("Content-Disposition", "attachment;filename=\""+fileName+"\"");
            //注意:“cttachment;”不能少,否则浏览器会直接在新窗口中打开
        }


        //向浏览器发送要下载的文件数据
        String realPath = getServletContext().getRealPath("/imgs/1.jpg");//真正下载的文件数据路径在这里
        InputStream in = new FileInputStream(realPath);
        OutputStream out = response.getOutputStream();
        byte[] buf = new byte[1024];
        int len=0;
        while( (len=in.read(buf))!=-1 ){
            out.write(buf, 0, len);
        }
        out.close();
        in.close();
    }

}

演示结果:

两个小知识点:

1、servlet池~servlet在Tomcat中是单例

web.xml:

<servlet>
    <servlet-name>ThreadServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.ThreadServlet</servlet-class>
  </servlet>
 <servlet-mapping>
    <servlet-name>ThreadServlet</servlet-name>
    <url-pattern>/thread</url-pattern>
  </servlet-mapping>    

ThreadServlet.java:

package cn.hncu.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ThreadServlet extends HttpServlet {
    private String name;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        name = request.getParameter("name");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        response.getWriter().print(name);
    }

}

演示结果:

注意看地址栏,和页面输出!!!!360浏览器先访问,在3s内再用火狐访问!

本例(通过两个浏览器分别发一个上传用户名的请求)输出结果,可会出现:第一个请求显示出的name是第二个请求上传的参数值。
本例告诉我们,servlet在Tomcat中其实是单例,多个请求其实是共享servlet池中的同一个对象,因此该对象中的成员变量是共享的,容易出现串数据。
尤其是servlet功能比较复杂的时候,可能会写多个方法,然后以要共用变量,很可能会想到把它定义成成员变量,这时就是一个坑!!!—–应该通过别的办法去解决,如通过方法参数传递,,数据库等等

2、自定义404页面,就是自己网站没有这个网址时,进入自己写的404页面中!

默认Servlet,当请求的路径在web.xml中没有匹配上,那么就导向该servlet,避免客户端出现404这些找不到资源的错误。注意,它可能会屏蔽掉我们放在安全目录以外的有效的资源(因为这些路径没有在web.xml中配置)
默认Servlet通过只会在项目正式发布时配置,测试阶段一般不会,因为我们无法看到具体的出错信息。

web.xml:

<servlet>
    <servlet-name>DefaultServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.DefaultServlet</servlet-class>
  </servlet>
<servlet-mapping>
    <servlet-name>DefaultServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>    

关键就是这句:<url-pattern>/</url-pattern>

DefaultServlet.java:

package cn.hncu.servlets;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DefaultServlet extends HttpServlet {


    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        String str="<h1><font color=\"red\">404,找不到页面啦,主人!</font></h1>";
        out.print(str);

        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }


}
目录
相关文章
|
2月前
|
Java 容器
【学习笔记】Jsp与Servlet技术
【学习笔记】Jsp与Servlet技术
73 0
|
16天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
2月前
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
Lua的面向对象编程、协同线程与协同函数的概念和使用,以及Lua文件I/O操作的基本方法。
32 4
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
20 3
|
2月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
37 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
30 2
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
34 1
|
2月前
|
Java C++
【多线程】JUC的常见类,Callable接口,ReentranLock,Semaphore,CountDownLatch
【多线程】JUC的常见类,Callable接口,ReentranLock,Semaphore,CountDownLatch
34 0
|
2月前
|
Java 应用服务中间件 Spring
【终极解决方案】Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
【终极解决方案】Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
26 0
|
4月前
|
C# 数据可视化 开发者
WPF开发者福音:深度解析OxyPlot与LiveCharts图表库,轻松实现数据可视化不再是难题!
【8月更文挑战第31天】在WPF应用中,数据可视化对提升用户体验至关重要。本文介绍并演示了两种流行图表库OxyPlot和LiveCharts的集成与使用方法。OxyPlot是一款适用于.NET应用的开源图表库,提供多种图表类型,易于集成。LiveCharts则以其丰富的图表类型和动画效果,特别适合实时数据展示。通过具体代码示例,本文展示了如何利用这两种图表库创建折线图和柱状图,并详细说明了安装和配置步骤。希望本文能帮助开发者在WPF应用中轻松实现高效、美观的数据可视化。
206 0