jsp-servlet开发

STS中开发步骤

建普通jsp项目过程

1.建项目(非Maven项目)
new----project----other----Web----Dynamic Web Project
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.下载包放到LIB目录中,如果是Maven项目可以自动导包(pom.xml中设置好)
在这里插入图片描述
3.设置工作空间,网页的编码(我常用UTF-8)
在这里插入图片描述
在这里插入图片描述
3.分层(dao,vo,servlet…)

一个构建maven项目的过程

《1》
image.png
《2》
image.png

《3》配置maven
image.png
《4》下图中,爆红,是因为,sts开发工具的Dynamic Web Module模式版本太低了,现在我们都3.x了,这里还是2.5,如下面第二图所示。
image.png
image.png
处理办法:
      先去掉那个勾选,再点应用(apply),选勾选3.1版本,同时到下面点击’Further configuration available…',我们勾选Generate web.xml。。。,让项目自建web.xml文件。
image.png
《5》,build path,即增加jdk库,apache库
image.png

         一个自已写的settings.xml,里面没有设置从远程仓库上传,下载功能,只设了阿里云下载镜像包。对IDEA 也适用,我事后把下载的路径设定好,再解压软件压缩该文件夹,下次用时,直接解压用之

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  

  <localRepository>C:\Users\Administrator\Desktop\maven\repository</localRepository>
 
  <pluginGroups>
     <pluginGroup>org.codehaus.plugins</pluginGroup>
  </pluginGroups>

 
  <proxies>
   
  </proxies>
 <mirrors>
  
  <mirror>
        <id>aliyunmaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <mirrorOf>central</mirrorOf>
     </mirror>  
  </mirrors>
<profiles>
<!--jdk版本一劳永逸的改法,因为系统默认为1.5版,太扯了-->
     <profile>
      <id>jdk-1.8</id>
      <activation>
       <activeByDefault>true</activeByDefault>
        <jdk>jdk1.8</jdk>
       </activation>
      <properties>
     <maven.compiler.source>1.8</maven.compiler.source>
     <maven.compiler.target>1.8</maven.compiler.target>
     <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
     </properties>
    </profile>
 </profiles>
<!--激活下载仓库预文件-->
 
 <activeProfiles>
    <activeProfile>myProfile</activeProfile>
    
  </activeProfiles>
</settings>

配置pom.xml,下面导了spring5,springmvc等包

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>cn.ybzy.ssmweb</groupId>
	<artifactId>ssmweb</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>5.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>5.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>5.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.2</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.25</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.taglibs</groupId>
			<artifactId>taglibs-standard-spec</artifactId>
			<version>1.2.5</version>
			<type>bundle</type>
		</dependency>
		<dependency>
			<groupId>org.apache.taglibs</groupId>
			<artifactId>taglibs-standard-impl</artifactId>
			<version>1.2.5</version>
			<type>bundle</type>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.18</version>
		</dependency>
		<dependency>
			<groupId>com.oracle.database.jdbc</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11.2.0.4</version>
		</dependency> 
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.2</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.6</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>1.3.7</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis.caches</groupId>
			<artifactId>mybatis-ehcache</artifactId>
			<version>1.1.0</version>
		</dependency>
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>5.1.4</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>5.0.6.RELEASE</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
			</plugin>
		</plugins>
	</build>

</project>

配置spring.xml,springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<!-- 指定spring扫描注解的范围,和springmv区分开发,避免重复扫描 -->
	<context:component-scan
		base-package="cn.ybzy.ssmweb">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
		<context:exclude-filter type="annotation"
			expression="org.springframework.web.bind.annotation.ControllerAdvice" />
	</context:component-scan>

	<!-- 与数据库链接的一些基本信息的配置,使用数据库连接池的配置 -->
	<context:property-placeholder
		location="classpath:jdbc.properties" />
	<!-- 配置C3P0数据连接池 -->
	<bean id="dataSource"
		class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

		<property name="acquireIncrement"
			value="${jdbc.acquireIncrement}"></property>
		<property name="initialPoolSize"
			value="${jdbc.initialPoolSize}"></property>
		<property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
		<property name="maxStatements" value="${jdbc.maxStatements}"></property>
		<property name="maxStatementsPerConnection"
			value="${jdbc.maxStatementsPerConnection}"></property>
	</bean>


	<!-- 事务配置 -->
	<!-- 事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<!-- 整合Mybatis -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:mybatisConfig.xml"></property>
		<property name="mapperLocations" value="classpath:cn/ybzy/ssmweb/mapper/*.xml"></property>
	</bean>
	<!-- 配置事务属性 -->
	<tx:advice id="txAdvice"
		transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true" />
			<tx:method name="load*" read-only="true" />
			<tx:method name="find*" read-only="true" />
			<tx:method name="select*" read-only="true" />
			<tx:method name="*" read-only="false" />
		</tx:attributes>
	</tx:advice>

	<!-- 配置事务的切入点 -->
	<aop:config>
		<aop:pointcut
			expression="execution(* cn.ybzy.ssmweb.service.*.*(..))" id="txPointcut" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
	</aop:config>
  <!-- spring只操作该包下面的文件,将mapper下的mapper接口(已实现数据库操作的接口类的xml文件),放进spring的IOC容器中,再让其它地方自动@Autowired -->
   <mybatis-spring:scan base-package="cn.ybzy.ssmweb.mapper"/>

</beans>

配置了视图(jsp文件)解析器,视图文件放在value="/WEB-INF/views/"目录中。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
		
	<!-- 配置springmvc扫描的注解,和spring划清界限 -->
	<context:component-scan base-package="cn.ybzy.ssmweb" use-default-filters="false">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
		<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
	</context:component-scan>
	
    <mvc:annotation-driven />
	
     <!-- springmvc的默认使用的视图解析器,配置前缀和后缀 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<!-- 让springmvc自动识别那些静态资源,不要用视图解析器去解析 -->
	<mvc:default-servlet-handler/>
	</beans>

各种路径的获取方法

1Java Resources的类路径的根路径

        String Path=this.getClass().getResource("/").getPath();
	    System.out.println("thisgetClassgetResourcePath="+Path);
	    String fontsPath=this.getClass().getResource("/").getPath()+"static/fonts/";
//thisgetClassgetResourcePath=/C:/Users/Administrator/Desktop/STSWORKSPACE/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/jspservlet/WEB-INF/classes/
//URL,获取类路径IDEA中
        URL path1 = this.getClass().getResource("");
        System.out.println(path1);   //  /C:/Users/Administrator/Desktop/IODemo/out/production/io1/cn/ybzy/demo/
      //利用线程类获取类路径根路径
       path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        System.out.println("Threadpath:"+path);

      IDEA
在这里插入图片描述
      IDEA JAVA工程的类路径下(相对于maven工程来说)

public class IOTest {
    public static void main(String[] args){
        IOTest it1=new IOTest();
        it1.getUrl();
    }
    public void getUrl(){
        String path = "";
        path=this.getClass().getResource("/").getPath();
        System.out.println("1:"+path);   //  /C:/Users/Administrator/Desktop/IODemo/out/production/io1/
        path=this.getClass().getResource("").getPath();
        System.out.println("2:"+path);  //  /C:/Users/Administrator/Desktop/IODemo/out/production/io1/cn/ybzy/demo/
    }

}

      STS/ECPLISE
在这里插入图片描述

2,同一目录下,只要写文件名即可
3.jsp中获取servlet路径

<!-- 1.表单,该提交是一种转发到下一个路径,request域中的对象(一般是键值对的形式)会传递下去-->
<body>
  欢迎购买: <%=book.getBookname() %>
 <form action="/jspservlet/servlet/AddServlet" method="post">
 <!--<form action="${pageContext.request.contextPath}/servlet/AddServlet" method="post">   建议用这种EL表达式写法,这样不管该项目怎么改名都可以用-->
   书本价格:<%=book.getBookprice() %><br>
   <input name="bookno" type="hidden" value="<%=book.getBookno() %>">
   <input name="bookname"  type="hidden" value="<%=book.getBookname() %>">
   <input name="bookprice" type="hidden" value="<%=book.getBookprice() %>">
   <input type="submit" value="购买">
 
 </form>

<!-- 2.jsp:forward 不用绝对路径也可,该跳转可保存request空间的属性值传到要转到的页面或servlet-->
<body>
   <jsp:forward page="servlet/PageServlet2"></jsp:forward>
</body>

<!--3.链接-->
<a href="/项目名/xxxx/.....">执行相关逻辑</a>

<!-- 4 response.sendRedirect("xxx")该跳转不共享request的值,session,application这些不受影响-->

4.servlet跳转与转发到jsp页

//1 doPost或doGet方法,参数实例化了request,response,不用自已创建,跳转(也叫重定向),不会共享request域中的属性
   //跳转要写绝对路径名,不能用'/'表示项目根,要带上项目名
resp.sendRedirect("/jspservlet/showAllBook.jsp");
//resp.sendRedirect(req.getContextPath()+"/jspservlet/showAllBook.jsp");    //建议用这种写法,因为以后项目改项目名很方便

//2 doPost或doGet方法,参数实例化了request,response,不用自已创建,这里'/‘表示 '/jspservlet'
RequestDispatcher rd = req.getRequestDispatcher("/showStudents.jsp");
 rd.forward(req, resp);

5.获得项目根路径
假如项目名为manventest,不过这里不是工作空间中项目的根目录,而运行后的项目根目录,STS/ECLIPSE中如下:

String des = request.getRealPath("/");
//String des = application.getReqlPath("/");
//C:\Users\Administrator\Desktop\STSWORKSPACE\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\maventest\


//获取根目下的文件即可这样写
<jsp:forward page="/writePdf.pdf"></jsp:forward>

利用java File类获取物理上项目的根路径,不是上面编译后字节码文件的根路径

public class IOTest {
    public static void main(String[] args) throws IOException {
        IOTest it1=new IOTest();
        it1.getUrl();
    }
    public void getUrl() throws IOException {
        String path = "";
        path=this.getClass().getResource("/").getPath();
        System.out.println("1:"+path);   //  /C:/Users/Administrator/Desktop/IODemo/out/production/io1/
        path=this.getClass().getResource("").getPath();
        System.out.println("2:"+path);  //  /C:/Users/Administrator/Desktop/IODemo/out/production/io1/cn/ybzy/demo/

        //利用File类,System类获取项目根路径
        File file = new File("");
        path = file.getCanonicalPath();   //抛出异常,我丢给方法上了,调用它用try catch或也丢给方法上
        System.out.println("Filepath:"+path);
        path = System.getProperty("user.dir");
        System.out.println("Systempath:"+path);

    }

}

在这里插入图片描述

jsp-servlet验证码开发

1.index.jsp嵌入由下面的servlet生成的图片并刷新可重新获得验证码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录界面</title>
    <script>
        function reloadCode() {
           var time=new Date().getTime();
          document.getElementById("imagecode").src="<%= request.getContextPath()%>/servlet/ImageServlet?date="+time;
        }
       /* js部分的Date相关是防止浏览器缓存后不能正常刷新,添加时间的唯一性来实现能够及时刷新和展示。

        js 部分可以参阅:JavaScript 语言入门

        也可以在ImageServlet中添加防止浏览器缓存的语句:

        response.setHeader("Pragma", "No-cache");*/
   
    </script>
</head>
<body>
<form action="<%= request.getContextPath()%>/servlet/ValidateServlet" method="get" >
           请您输入账号:
			<input type="text" name="account" />
			<BR>
			请您输入密码:
			<input type="password" name="password" />
			<BR>
    验证码:<input  type="text" name="checkCode"/><br/>
    <img alt="验证码" id="imagecode" src="<%= request.getContextPath()%>/servlet/ImageServlet"/>
    <a href="javascript:reloadCode();">看不清楚</a><br>
    <br/><input type="submit" value="提交">
</form>
</body>
</html>

2.Servelt生成验证码图片

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ImageServlet  extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    	
        BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);//创建图像缓冲区
        Graphics g = bi.getGraphics();      //通过缓冲区创建一个画布
        Color c = new Color(200, 150, 255); //创建颜色
        g.setColor(c);                     //为画布创建背景颜色
        g.fillRect(0, 0, 68, 22);           //填充矩形
        char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();//转化为字符型的数组
        Random r = new Random();
        int len = ch.length;
        int index;                           //index用于存放随机数字
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            index = r.nextInt(len);               //产生随机数字
            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));  //设置颜色
            g.drawString(ch[index] + "", (i * 15) + 3, 18);   //画数字以及数字的位置
            sb.append(ch[index]);
        }
        request.getSession().setAttribute("piccode", sb.toString());
        ImageIO.write(bi, "JPG", response.getOutputStream());
    }
}

3.Servlet逻辑判断验证是否正确,再进行相应的跳转

public class ValidateServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setHeader("Pragma", "No-cache");
		response.setContentType("text/html;charset=utf-8");//解决乱码问题
		//得到提交的验证码
		String code = request.getParameter("checkCode");
		//获取session中的验证码
		HttpSession session = request.getSession();
		String randStr = (String)session.getAttribute("piccode");
		response.setCharacterEncoding("utf8");
		PrintWriter out = response.getWriter();
		if(!code.equals(randStr)){
			out.println("验证码错误!");
		}
		else{
			out.println("验证码正确!跳转到LoginServlet......");
		}	
		out.flush();//将流刷新
        out.close();//将流关闭
	}

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

4.测试
我首先:生成验证码图片看看
http://localhost/yanzhengma/index.jsp
在这里插入图片描述
然后,测试提交效果。
在这里插入图片描述
在这里插入图片描述

JFreeChart开发图片报表

在web开发过程中,经常需要将数据以比较直观的方式显示出来,此时报表能够起到很好的作用。
JAVA技术报表的代表产品有:JFreeChart,JasperReports,iReport,FineReport,iText等。

下载JFreeChart包

https://sourceforge.net/projects/jfreechart/

下载后解压:到解压的文件目录的lib下复制如下两个文件到WebContent目录WEB-INF的lib目录下
在这里插入图片描述
1.web.xml

<servlet>
     <servlet-name>DisplayChart</servlet-name>
     <servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>DisplayChart</servlet-name>
    <url-pattern>/DisplayChart</url-pattern>
  </servlet-mapping>

1.1开发柱状报表
《1》。实例化数据集org.jfree.data.category.DefaultCategoryDataset类
《2》,添加数据给DefaultCategoryDatase对象,当然也可以从数据库中查询

datase.addValue(value1,value2,value3);

         value1为纵坐标的值,value2是纵坐标中的各个项目的种类,value3是横坐标中各个项目的种类。实际上,value1即为人数数据,value2可以为NULL,因为纵坐标没有对人数进行细分。
《3》。通过工厂类org.jfree.chart.ChartFactory创建柱状报表。

JFreeChart chart = ChartFactory.createBarChart(value1,value2,value3,value4,value5,false,false,false);

         各参数的意义如下

value1:表示柱状报表的标题,
value2:表示柱状表的横坐标名称,如“成绩”
value3:表示。。。。纵坐标的名称,如‘人数’
value4:数据集
value5:表示的是所作之图是水平还是坚直,可以用org.jfree.chart.plot.PlotOrientation的常量表示
             .VERTICAL 和 .HORIZONTAL

《4》。用org.jfree.chart.servlet.ServletUtilities将chart保存为图片,确定宽,高,并确定保存的范围(一般session)然后组图片路径。

String filename = ServeltUtilities.saveChartAsPng(chart,width,height,session);
String graphUrl = "/项目名/DisplayChart?filename="+filename;

《5》设置中文体体,在jsp页面中显示图片

    Font font = new Font("隶书", Font.PLAIN, 20);
     StandardChartTheme stheme=new StandardChartTheme("CN"); 
     stheme.setExtraLargeFont(font);                             //设置标题字体
     stheme.setLargeFont(new Font("宋书",Font.PLAIN,20));         //设置轴向字体
     stheme.setRegularFont(font);                                 //设置图例字体
     ChartFactory.setChartTheme(stheme);              //应用字体功能

jsp页中显示图片

<img src="<%=graphURL%"></img>

案例:显示男女成绩分布报表

<%@page import="org.jfree.data.general.DatasetUtilities"%>
<%@page import="org.jfree.data.category.CategoryDataset"%>
<%@page import="org.jfree.chart.StandardChartTheme"%>
<%@page import="org.jfree.chart.servlet.ServletUtilities"%>
<%@page import="org.jfree.chart.JFreeChart"%>
<%@page import="org.jfree.chart.plot.PlotOrientation"%>
<%@page import="org.jfree.chart.ChartFactory,java.awt.*"%>
<%@page import="org.jfree.data.category.DefaultCategoryDataset"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>柱状报表2美化了</title>
</head>

<body>
 <%
     double[][] data = new double[][]{{1,2},{3,5},{7,5},{7,8},{2,6}};
     String[] rowKeys = new String[]{"优秀","良好","中等","及格","不及格"};
     String[] columnKeys = {"男","女"};
     
     Font font = new Font("隶书", Font.PLAIN, 20);
     StandardChartTheme stheme=new StandardChartTheme("CN"); 
     stheme.setExtraLargeFont(font);                             //设置标题字体
     stheme.setLargeFont(new Font("宋书",Font.PLAIN,20));         //设置轴向字体
     stheme.setRegularFont(font);                                 //设置图例字体
     ChartFactory.setChartTheme(stheme); 
     
     CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys,columnKeys,data);
     JFreeChart chart =ChartFactory.createBarChart3D("考试成绩统计表(按性别)","成绩","人数",dataset,PlotOrientation.VERTICAL,true,false,false); 
     String filename = ServletUtilities.saveChartAsPNG(chart,600,400,session);
     String graphURL = "/jfreechart/DisplayChart?filename="+filename;
 
   %>
<img src="<%=graphURL %>">
</body>
</html>

测试 http://localhost:8080/jfreechart/barchar2.jsp
在这里插入图片描述
1.2开发饼状报表

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>饼状报表</title>
</head>
<body>
 <%
        DefaultPieDataset dataset = new DefaultPieDataset();
        dataset.setValue("优秀",0.45);
        dataset.setValue("良好",0.3);
        dataset.setValue("中等",0.1);
        dataset.setValue("及格",0.05);
        dataset.setValue("不及格",0.1);
        
        Font font = new Font("隶书", Font.PLAIN, 20);
        StandardChartTheme stheme=new StandardChartTheme("CN"); 
        stheme.setExtraLargeFont(font);                             //设置标题字体
        stheme.setLargeFont(new Font("宋书",Font.PLAIN,20));         //设置轴向字体
        stheme.setRegularFont(font);       //设置图例字体
        ChartFactory.setChartTheme(stheme); 
        
        JFreeChart chart = ChartFactory.createPieChart3D("考试成绩统计图",dataset,true,false,false);
        
        
        String filename = ServletUtilities.saveChartAsPNG(chart,600,400,session);
        String graphURL = "/jfreechart/DisplayChart?filename="+filename;
     %>
     <img src="<%=graphURL %>"></img>
</body>
</html>

1.3曲线报表
         下面是双曲线,单曲线只要减少一个TimeSeries对象即可。

@page import="org.jfree.chart.servlet.ServletUtilities"%>
<%@page import="org.jfree.chart.title.TextTitle"%>
<%@page import="org.jfree.data.time.Month"%>
<%@page import="org.jfree.data.time.TimeSeries"%>
<%@page import="org.jfree.data.time.TimeSeriesCollection"%>
<%@page import="org.jfree.chart.ChartFactory"%>
<%@page import="java.awt.*"%>
<%@page import="org.jfree.chart.StandardChartTheme"%>
<%@page import="org.jfree.chart.JFreeChart"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>

<title>曲线图报表</title>
</head>
<body>
<%

   TimeSeriesCollection lineDataset = new TimeSeriesCollection();
   TimeSeries timeSeries = new TimeSeries("熊少文",Month.class);
   timeSeries.add(new Month(1,2024),85);
   timeSeries.add(new Month(2,2024),76);
   timeSeries.add(new Month(3,2024),65);
   timeSeries.add(new Month(4,2024),80);
   timeSeries.add(new Month(5,2024),66);
   timeSeries.add(new Month(6,2024),72);
   timeSeries.add(new Month(7,2024),83);
   timeSeries.add(new Month(8,2024),88);
   timeSeries.add(new Month(9,2024),85);
   timeSeries.add(new Month(10,2024),74);
   timeSeries.add(new Month(11,2024),78);
   timeSeries.add(new Month(12,2024),63);
   lineDataset.addSeries(timeSeries);
   TimeSeries timeSeries2 = new TimeSeries("徐会凤",Month.class);
   timeSeries2.add(new Month(1,2024),98);
   timeSeries2.add(new Month(2,2024),95);
   timeSeries2.add(new Month(3,2024),89);
   timeSeries2.add(new Month(4,2024),88);
   timeSeries2.add(new Month(5,2024),86);
   timeSeries2.add(new Month(6,2024),82);
   timeSeries2.add(new Month(7,2024),93);
   timeSeries2.add(new Month(8,2024),98);
   timeSeries2.add(new Month(9,2024),85);
   timeSeries2.add(new Month(10,2024),74);
   timeSeries2.add(new Month(11,2024),78);
   timeSeries2.add(new Month(12,2024),83);
   lineDataset.addSeries(timeSeries2);
   JFreeChart chart = ChartFactory.createTimeSeriesChart("每月考试成绩","月份","成绩",lineDataset,true,false,false);

   Font font = new Font("隶书", Font.PLAIN, 20);
   StandardChartTheme stheme=new StandardChartTheme("CN"); 
   stheme.setExtraLargeFont(font);                             //设置标题字体
   stheme.setLargeFont(new Font("宋书",Font.PLAIN,20));         //设置轴向字体
   stheme.setRegularFont(font);                                 //设置图例字体
   ChartFactory.setChartTheme(stheme);
  
   
   //设置子标题  
   TextTitle subTtitle = new TextTitle("2024年度");
   chart.addSubtitle(subTtitle);
   //设置主标题 
   chart.setTitle(new TextTitle("每月月考成绩"));
   chart.setAntiAlias(true);
   String filename = ServletUtilities.saveChartAsPNG(chart,600,400,session);
   String graphURL =request.getContextPath()+"/DisplayChart?filename="+filename;
 %>
<img src="<%=graphURL%>">
</body>
</html>

在这里插入图片描述

iText开发动态PDF报表

      pdf是由服务器生成的,不是客户端生成的。
      该应用,我用maven项目来做,因为iText pdf java包太难自主下载了,我用maven自动下载。

  1. 新建一个maven工程 maventest

    在这里插入图片描述

  2. 导包pom.xml

 <dependencies>
     <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.1.9</version>
            <type>pom</type>
       </dependency>
  </dependencies>
  1. 建一个jsp页面,创建一个空白文档
    在这里插入图片描述
<%@page import="com.itextpdf.layout.Document"%>
<%@page import="com.itextpdf.kernel.pdf.PdfDocument"%>
<%@page import="com.itextpdf.kernel.pdf.PdfWriter"%>
<%@page import="com.itextpdf.kernel.pdf.DocumentProperties"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
   pageEncoding="UTF-8"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 <%

  String des="C:\\";
  String dest = des+"sample.pdf";
  PdfWriter writer = new PdfWriter(dest);
  // 2、创建一个 PdfDocument,参数为PdfWriter
  PdfDocument pdfDoc = new PdfDocument(writer);

   // 3、用PdfDocument创建一个空白 page 
    pdfDoc.addNewPage();

    // 4、创建一个 Document,参数为PdfDocument
     Document document = new Document(pdfDoc);
   // 5、关闭 document,PdfDocument
     document.close();
    pdfDoc.close();
%>
</body>
</html>

3.下面是创建分页,段落,表格,设置pdf页面大小,边距等示例

<%
    String des="C:\\";
 //创建分页
      //创建区域中断对象AreaBreak,结果是两页的空白页
      /*String dest = des+"addingAreaBreak.pdf";
       PdfWriter writer = new PdfWriter(dest);
       PdfDocument pdf = new PdfDocument(writer);
       Document document = new Document(pdf);

       // 创建一个 Area Break
       AreaBreak aB = new AreaBreak();

       // 添加到 PDF
       document.add(aB);
       document.close();
       pdf.close();*/
   //创建两个段落
     /*String dest = des+"addingParagraph.pdf";
     PdfWriter writer = new PdfWriter(dest);
     PdfDocument pdf = new PdfDocument(writer);
     Document document = new Document(pdf);

   String para1 = "段落1的内容";

   String para2 = "段落2的内容";

     // 创建段落 Paragraphs
     Paragraph paragraph1 = new Paragraph(para1);
     Paragraph paragraph2 = new Paragraph(para2);

    // 把段落添加到 document
     document.add(paragraph1);
     document.add(paragraph2);

     // 关闭
      document.close();
     pdf.close();*/
   
   //创建一个表格
      //创建一个 Table 对象
        
          String dest = des+"addingTable.pdf";
          PdfWriter writer = new PdfWriter(dest);
          PdfDocument pdf = new PdfDocument(writer);
          //设置pdf页面大小,边距等
          Document doc = new Document(pdf,PageSize.A8);
       
          doc.setBottomMargin(40);
          doc.setLeftMargin(40);
          doc.setRightMargin(40);
          doc.setTopMargin(50);
          
          // 创建表格 table
          //三个参数代表这个表格有三列,每列的宽度是150
          float [] pointColumnWidths = {150F, 150F, 150F};
          Table table = new Table(pointColumnWidths);
   
          // 逐个单元格添加内容到表格 table
          table.addCell("表头1内容");
          table.addCell("表头2内容");
          table.addCell("表头3内容");
          table.addCell("单元格1内容");
          table.addCell("单元格2内容");
          table.addCell("单元格3内容");
   
          //把表格添加到document
          doc.add(table);
   
          // 关闭
          doc.close();
          pdf.close();
        
   


   %>
</body>

4.中文输出和字体解决
      宋体细体,ITEXT本身有,可以直接使用。使用它就能输出中文。
      这里添加了华文琥珀和黑体两个字体,将字体拷贝的项目的资源目录下,不拷贝也行,定义的路径直接指向系统字体库。
在这里插入图片描述
STS/ECLIPSE中,static要放在WEB-INF-classes中,没有classes文件夹,自行创建
在这里插入图片描述

 //字体设置,解决中文输出问题 宋体细体,ITEXT集成的。
        PdfFont  sysFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H");
        // 创建字体  STHUPO.TTF 华文琥珀,simhei.ttf黑体
        //定义字体存放路径
        String fontsPath=this.getClass().getResource("/").getPath()+"static/fonts/";
        PdfFont boldFont = PdfFontFactory.createFont(fontsPath+"STHUPO.TTF", PdfEncodings.IDENTITY_H,true);
        PdfFont heitiFont = PdfFontFactory.createFont(fontsPath+"simhei.ttf", PdfEncodings.IDENTITY_H,true);
 
        //添加首页标题,字体大小30
        Text titleText=new Text("健康体检报告").setFont(boldFont).setFontSize(30);
        Paragraph titelPara=new Paragraph(titleText);
        //设置对齐方式,上边距30,下边距30,文本居中
        document.add(titelPara.setMarginTop(30).setMarginBottom(30).setTextAlignment(TextAlignment.CENTER));

5.添加图片
         注意:要添加到已有pdf文件,该文件已存,如果没有,执行(http://localhost:8080/项目名/xxx.jsp)两遍即可。

<%@page import="com.itextpdf.layout.Document"%>
<%@page import="com.itextpdf.kernel.pdf.canvas.PdfCanvas"%>
<%@page import="com.itextpdf.kernel.pdf.PdfPage"%>
<%@page import="com.itextpdf.layout.element.Image"%>
<%@page import="com.itextpdf.io.image.ImageDataFactory"%>
<%@page import="com.itextpdf.io.image.ImageData"%>
<%@page import="com.itextpdf.kernel.pdf.PdfDocument"%>
<%@page import="com.itextpdf.kernel.pdf.PdfWriter"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
   pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<title>pdf图片</title>
</head>
<body>
<%
   //String des = "C:\\";
   String des = application.getRealPath("/");
   String dest = des+"addingImage.pdf";
   
   PdfWriter writer = new PdfWriter(dest);
   PdfDocument pdf = new PdfDocument(writer);
   Document doc = new Document(pdf);

  String imagePath=this.getClass().getResource("/").getPath()+"static/image/43.jpg";
  Image image = new Image(ImageDataFactory.create(imagePath));
  image.setFixedPosition(10,25);     //设置位置
  image.setAutoScale(true);        //自动适配图像,让图像整个显示(像素大的话有效果)
  image.setRotationAngle(45);      //旋转图片
  doc.add(image);
  doc.close();
  response.setHeader("Content-Dispostion","attachment;filename=addingImage.pdf");
  response.setContentType("applicatin/pdf");   //表示出现下载保存对话框
%>
 <jsp:forward page="/addingImage.pdf"></jsp:forward>
</body>
</html>

效果图
在这里插入图片描述

6.写入文字到pdf中


<body>
<%  
   //String des = "C:\\";
   //String des=application.getRealPath("/");   //request.getRealPath();功能也一样,不过不推荐用。
   String des = request.getRealPath("/");
   
   String dest = des+"writePdf.pdf";
   String msg = "This is Test";
   PdfWriter writer = new PdfWriter(dest);
   PdfDocument pdf = new PdfDocument(writer);
   Document doc = new Document(pdf);
   doc.add(new Paragraph(msg));
   doc.close();
%>
</body>

7.读取pdf的文本

<%


try {
   // 初始化 PDF 文档
   String filename = application.getRealPath("/")+"writePdf.pdf";
   PdfDocument pdfDoc = new PdfDocument(new PdfReader(filename));

   // 遍历 PDF 文档中的每一页
   for (int page2 = 1; page2 <= pdfDoc.getNumberOfPages(); ++page2) {
       String pageContent = PdfTextExtractor.getTextFromPage(pdfDoc.getPage(page2));
       out.println(pageContent);
       System.out.println(pageContent);
   }

   // 关闭 PDF 文档
   pdfDoc.close();
} catch (IOException e) {
   e.printStackTrace();
}


%>

8.添加列表

<% 
     String des = request.getRealPath("/");

    String dest = des+"addList.pdf"; 
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);                    
    Document document = new Document(pdf);  
    Paragraph paragraph = new Paragraph("Tutorials Point provides the following tutorials");
    List list = new List();  
    
    // Add elements to the list       
    list.add("Java");       
    list.add("JavaFX");      
    list.add("Apache Tika");       
    list.add("OpenCV");       
    list.add("WebGL");       
    list.add("Coffee Script");       
    list.add("Java RMI");       
    list.add("Apache Pig"); 
    document.add(paragraph);                    
    
    // Adding list to the document       
    document.add(list);
    
    // Closing the document       
    document.close();              
    System.out.println("List added"); 
%>

在这里插入图片描述

Servlet基础

Servlet接口

      Servlet是一个接口,我们可以实现它,创建自已定义的一个Servlet类。

public class MyFirstServlet implements Servlet{
	 public MyFirstServlet() {
		System.out.println("MyFirstServlet");
	}

	@Override
	public void destroy() {
		System.out.println("destroy");
		
	}

	@Override
	public ServletConfig getServletConfig() {
		System.out.println("getServletConfig");
		return null;
	}

	@Override
	public String getServletInfo() {
		System.out.println("getServletInfo");
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		System.out.println("init");
		
	}

	@Override
	public void service(ServletRequest arg0, ServletResponse res) throws ServletException, IOException {
		res.getWriter().write("xiongshaowen");
		System.out.println("service");
	}

}
----------------------------------------------------web.xml配置------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"......>
  <servlet>
     <servlet-name>MyFirstServlet</servlet-name>
     <servlet-class>cn.xiong.demo.MyFirstServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>MyFirstServlet</servlet-name>
    <url-pattern>/MyFirstServlet</url-pattern>
  
  </servlet-mapping>
</web-app>

-------------------------------------启动Tomcat服务器,再浏览器打开后控制台显示---------------------------------------------------
MyFirstServlet
init
service
service
service
...

在这里插入图片描述

  1. 构造方法,最先被执行,构造方法被执行意味着创建新的实例,且只会被执行一次,意味着Servlet是单例的,在整个Servlet容器中每个具体的Servlet实现类都只有一个实例!

  2. init:构造方法之后,马上被执行,且只执行一次,作用是做初始化,虽然构造方法也能做初始化操作,但init(ServletConfig arg0)是带了参数回来的,作用更大,后面在具体讲这个参数。

  3. service:被多次调用,每次在浏览器刷新请求都会调用一次service方法,实际用于对请求的响应。

  4. destroy:只被调用一次,当前Servlet所在的web应用被卸载前执行,用于释放Servlet占用的计算机资源。

——web.xml中Servlet映射配置中整数,这个配置的整数若为0或正整数时表示web应用启动的时候,自动执行对应的Servlet,整数越小,越优先执行,只执行一次随web应用启动时。若为负数,则会在第一次请求时被执行对象的Servler。

ServletConfig对象和ServletContext域对象

1.public void init(ServletConfig servletConfig)

      ServletConfig:Servlet配置,ServletConfig是一个接口,具体的实现是由Servlet容器开发商实现的,这里我们是以tomcat为例,就是tomcat实现的,具体这个参数的部分参数值,源头在web.xml配置文件中·
ServletConfig接口的定义的方法:

String getServletName()  -- 获取当前Servlet在web.xml中配置的名字
String getInitParameter(String name) -- 获取当前Servlet指定名称的初始化参数的值
Enumeration getInitParameterNames()  -- 获取当前Servlet所有初始化参数的名字组成的枚举
ServletContext getServletContext()  -- 获取代表当前web应用的ServletContext对象

web.xml配置参数的形式举例

<servlet>
     <servlet-name>MyFirstServlet</servlet-name>
     <servlet-class>cn.xiong.demo.MyFirstServlet</servlet-class>
       <init-param>   <!-- 配置本servlet的初始化参数:键值对的方式配的-->
         <param-name>username</param-name>
         <param-value>xiongshaowen</param-value>
       </init-param>
        <init-param>   <!-- 配置本servlet的初始化参数:可以配多个-->
           <param-name>xxx</param-name>
           <param-value>xxxxxxx</param-value>
       </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>MyFirstServlet</servlet-name>
    <url-pattern>/MyFirstServlet</url-pattern>
  
  </servlet-mapping>

java代码获取servlet的初始化参数值示例

    @Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init");
		String username=config.getInitParameter("username");
		System.out.println("username:"+username);
		
	}
-----------------------=------------------------------------------------------------------------------------------------
MyFirstServlet
init
username:xiongshaowen
service

获取多个servlet在web.xml配置多个参数名和值

@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init");
		Enumeration<String> enumeration = config.getInitParameterNames();
		while(enumeration.hasMoreElements()) {
			String name=(String) enumeration.nextElement();
			String value=config.getInitParameter(name);
			System.out.println("paramName:"+name+"value:"+value);
		}
		
	}

2.ServletContext:代表当前web应用(非常重要)
      WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
      ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
      由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
context中常用的方法有:

void setAttribute(String,Object);
Object getAttribute(String);
void removeAttribute(String);

应 用 1.建两个类都执行Servlet接口,首先都在init方法初始化ServletContext对象,在第一个类中保存一个域对象aaaa,并赋值1111,再在第二个类中用域对象获取对象名aaaa的值,并打印到控制台和页面上

-----------------------=--------ServletContextTest-------------------------------------------------------------
public class ServletContextTest implements Servlet{
    private ServletContext context;
	@Override
	public void destroy() {
		
		
	}

	@Override
	public ServletConfig getServletConfig() {
		
		return null;
	}

	@Override
	public String getServletInfo() {
		
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		this.context = arg0.getServletContext();
		
		
	}

	@Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		
		context.setAttribute("aaaa", "1111");
		
	}

}
-----------------------=--------ServletContextTest2------------------------------------------
public class ServletContextTest2 implements Servlet{
    private ServletContext context;
	@Override
	public void destroy() {
		
		
	}

	@Override
	public ServletConfig getServletConfig() {
		
		return null;
	}

	@Override
	public String getServletInfo() {
		
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		context=arg0.getServletContext();
		
	}

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
		String value=(String)context.getAttribute("aaaa");  //获取到ServletContextTest中保存的域对象aaaa的值
		System.out.println("value:"+value);   //输出到控制台上
		arg1.getWriter().println(value);     //输出到页面上
	}

}

启动TOmcat服务器,再到浏览器的地址栏中输入localhost:8080/项目名/ServletContextTest,回车后,再localhost:8080/项目名/ServletContextTest2回车

value:1111

在这里插入图片描述

应用 2 获取WEB应用的初始化参数(web.xml中配的)
      我们在上面,通过标签为某一个单独的servlet类加配置信息,这种配置信息在其他的Servlet实现类中是无法访问到的。可如果我们使用标签(与Servlet标签并列)为整个Web应用配置属性的话,那所有的Servlet类实例就都能访问里面的参数了。

<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
.....
  <context-param>  <!-- ServletContext可访问的全局初始化参数-->
      <param-name>username</param-name>
      <param-value>xiongshaowen</param-value>
 </context-param>
 .....
</web-app>
public class ServletContextTest implements Servlet{
    private ServletContext context;
	@Override
	public void destroy() {
		
		
	}

	@Override
	public ServletConfig getServletConfig() {
		
		return null;
	}

	@Override
	public String getServletInfo() {
		
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		this.context = arg0.getServletContext();
		
		
	}

	@Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		
		//context.setAttribute("aaaa", "1111");
		//获取web.xml中的<context-param>整个web应用的初始化参数值
		resp.getWriter().println(context.getInitParameter("username"));
		
	}

}
-------------------------------------------------------------------------------------------------------------
//会在启动服务后, http://localhost:8081/ServletTest/ServletContextTest
//网页上显示  xiongshaowen



// 一次性获取Context里所有的初始化参数
  Enumeration enumeration = context.getInitParameterNames();
   while (enumeration.hasMoreElements()) {
       String name = (String) enumeration.nextElement();
       String value = context.getInitParameter(name);
       System.out.println(name + ";" + value);
}

应用 3 、加载资源文件的获取:
      以上获取初始化参数都是在web.xml配置的,如果参数很多很多,那么在web.xml中配置是十分不好的事。
      ServletContext提供了getRealPath方法,在这个方法中传入一个路径,这个方法的底层会在传入的路径的前面拼接当前web应用的硬盘路径,从而得到当前资源的硬盘路径。例如:先在WebConteent的根目录下新建一个专门用了配置信息的文件为config.properties,里面的参数如下:
在这里插入图片描述

---------------------------config.properties----------------------------
username=admin
passwd=123456
---------------------ServletContextProperties.java--------------------------------------------------
public class ServletContextProperties implements Servlet{
    private ServletContext context;
	@Override
	public void destroy() {
		
		
	}

	@Override
	public ServletConfig getServletConfig() {
		
		return null;
	}

	@Override
	public String getServletInfo() {
		
		return null;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		context=config.getServletContext();
		
	}

	@Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		Properties properties = new Properties();
		String popFilePath = context.getRealPath("config.properties");
		System.out.println("config.properties文件在:"+popFilePath);
		properties.load(new FileReader(popFilePath));
		System.out.println(properties.getProperty("username"));
		
	}

}
----------------------------web.xml--------------------------------------
<servlet>
      <servlet-name>ServletContextProperties</servlet-name>
      <servlet-class>cn.xiong.demo.ServletContextProperties</servlet-class>
  </servlet>
  <servlet-mapping>
     <servlet-name>ServletContextProperties</servlet-name>
     <url-pattern>/ServletContextProperties</url-pattern>
  </servlet-mapping>

应用4、获取当前WEB应用的名称:

        context.getContextPath()

HTTP协议—GET和POST请求

http协议:自行查资料,本人在java网络编程中讲得很祥细。
URL:
锚部分:从“#”开始到最后,都是锚部分。
参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
HTTP之请求消息Request:
      客户端发送一个HTTP请求到服务器的请求消息包括以下格式:

      请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
在这里插入图片描述
HTTP之响应消息Response
      一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。
      HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文(HTML文档往往就在正文里头)。
状态行里有HTTP之状态码,以后在开发中用的到:
      状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:

1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求

get请求示例

--------------------------------------------index.jsp------------------
<body>

    <form action="/ServletTest/GetServlet" method="post">  <!-- 不过默认就是Get方式 -->
       <input name="aaa" type="text" value="1111">
       <input type="submit" value="提交请求">
       
       
    </form>

</body>
-----------------------------------------GetServlet.java-----------------
public class GetServlet implements Servlet {
	private ServletContext context;
     //中间的三个方法省略了,占遍幅,不要忘了,不过可以通过提醒自动生成所有要实现的方法
	@Override
	public void init(ServletConfig arg0) throws ServletException {
		this.context = arg0.getServletContext();
		
		
	}

	@Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		
		context.setAttribute("aaaa", "1111");
		//获取web.xml中的<context-param>整个web应用的初始化参数值
		resp.getWriter().println(context.getInitParameter("username"));
		
	}

}
------------------------------------web.xml-------------------------------------
<servlet>
      <servlet-name>GetServlet</servlet-name>
      <servlet-class>cn.xiong.get_post.GetServlet</servlet-class>
  </servlet>
  <servlet-mapping>
     <servlet-name>GetServlet</servlet-name>
     <url-pattern>/GetServlet</url-pattern>
  </servlet-mapping>

在这里插入图片描述
post请求示例,把表单的 method改为post,其它如上面的代码不变

<form action="/ServletTest/GetServlet" method="post">  <!-- 不过默认就是Get方式 -->
       <input name="aaa" type="text" value="1111">
       <input type="submit" value="提交请求">
 </form>

在这里插入图片描述
GET和POST请求的区别
GET请求

GET /books/?sex=man&name=Professional HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
注意最后一行是空行

POST请求

POST / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive

name=Professional%20Ajax&publisher=Wiley

  1. GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;这些数据都是键值对的格式。
    POST提交:把提交的数据放置在是HTTP包的包体中。
    因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变

  2. 传输数据的大小:首先声明:HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。但是部分浏览器对URL长度有限制
    GET:特定浏览器和服务器对URL长度有限制,例如 IE对URL长度的限制是2083字节(2K+35)。
    POST:由于不是通过URL传值,理论上数据不受限。

  3. GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.

ServletRequest接收GETPOST提交信息

      public void service(ServletRequest req, ServletResponse resp);该方法中参数实例两个对象,request,response对象。
ServletRequest:

String getParameter(String name) 最常用
Map getParameterMap(),返回键值对
Enumeration getParameterNames()
String[] getParameterValues(String name)第二常用

1.jsp文件中,提交请求数据

<body>

    <form action="/ServletTest/GetPostServlet" method="get">  <!-- 不过默认就是Get方式 -->
    <br/>
          请输入用户名:<input name="username" type="text" value="">
    <br/>
          请输入 密码:<input name="password" type="password">
     <br/>
        爱好:<input type="checkbox" name="aihao" value="lanqiu"/>篮球
         <input type="checkbox" name="aihao" value="tiaowu"/>跳舞
     <input type="submit" value="提交请求">
       
       
    </form>

</body>

Servlet实现类中,获取数据再响应给客户,我们在浏览器中看

   @Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		resp.setCharacterEncoding("utf-8");
		req.setCharacterEncoding("utf-8");
		String username=req.getParameter("username");
		String password = req.getParameter("password");
		
		resp.getWriter().println("输入的用户名:"+username);
		resp.getWriter().println("输入的密码:"+password);
		
		String[] ah=req.getParameterValues("aihao");
		for(int i=0;i<ah.length;i++) {
			resp.getWriter().println(ah[i]);
		}
   }
 ---------------------------------------------------------------------------------
 /ServletTest/GetPostServlet
/ServletTest
username=%E7%86%8A%E5%B0%91%E6%96%87&password=xiong&aihao=lanqiu&aihao=tiaowu

在这里插入图片描述

ServletResponse响应信息

ServletResponse里封装的常用方法:

resp.getWriter().println("输出到浏览器字符串"); 最常用
resp.setContentType("设置响应的内容类型,如word"); 类型可以在tomcat里的conf里的web.xml中找,如搜索doc,找word类型
httpServletResponse.sendRedirect("重定向,跳转");

。。。。具体到后面的知识点专门再讲。

作业:
在web.xml文件中设置两个WEB应用的初始化参数:user,password
定义一个login.html,包括一个form,输入用户名和密码,提交到loginServlet
在创建一个loginServlet来接收login.html发送来的信息,并判断浏览器发来的用户名和密码和web.xml里的值是否一样,一样在浏览器中输出login success,否则输出login field

自定义实现Servlet接口类

      如果不这么做,那每一次实现Servlet接口,都要实现那些方法,将是很烦心的事。我们定义一个类,然后让其它继承用,就不用实现那么多方法了。
自定义抽象类,它有一个抽象方法是service是改造自Servlet接口的,init方法初始一个ServletConfig对象,让getServletConfig返回之,继承该类的类只要实现抽像方法即可用之作业务逻辑功能

public abstract class MyGenericServlet implements Servlet {
    private ServletConfig config;
	@Override
	public void destroy() {
		
	}

	@Override
	public ServletConfig getServletConfig() {
		
		return this.config;
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		this.config=config;
		
	}

	@Override
	public abstract void service(ServletRequest req, ServletResponse resp) 
			throws ServletException, IOException;

}

应用示例:我把前面做的GetPostServlet让它继承MyGenericServlet

public class GetPostServlet extends MyGenericServlet{

	@Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		resp.setCharacterEncoding("utf-8");
		req.setCharacterEncoding("utf-8");
		
		String username=req.getParameter("username");
		String password = req.getParameter("password");
	//比较浏览器提交表单数据与web.xml中定义的全局参数数据比较,如果相等,则login success,否则login failed!	
	if(username.equals(getServletConfig().getServletContext().getInitParameter("username")) &&
				password.equals(getServletConfig().getServletContext().getInitParameter("password")))
			resp.getWriter().println("Login success!");
		else
			resp.getWriter().println("login failed!!");
		
	}

}

这就简明多了

HttpServlet

传统的Servlet,不能方便的区别浏览器的请求是GET,POST。
动手演示一下怎么个不方便!每次对请求都要进行转换判断!

HttpServletRequest httpreq = (HttpServletRequest) arg0;  
String method = httpreq.getMethod();    //这个很重要,我们处理网络数据时,常用到
System.out.println(method);

      所以我们为了日常开发方便,我们可以把复杂的东西封装一下,把复杂简单化!
自定义的MyHttpServlet,千万千万千万注意,这不是我们以后常用网络编程中的HttpServlet类,我做个这类也恰恰是解释HttpServlet类的原理

public class MyHttpServlet extends GenericServlet {
    
	private static final long serialVersionUID = 1L;

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
		try {
			HttpServletRequest hreq =(HttpServletRequest) arg0;
			HttpServletResponse hresp =(HttpServletResponse)arg1;
			this.service(hreq, hresp);
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}
	
	public void service(HttpServletRequest hreq, HttpServletResponse hresp) throws ServletException, IOException {
		String method=hreq.getMethod();
		if(method.equalsIgnoreCase("GET")) {  //判断是否相等,忽略大小写
			doGet(hreq,hresp);
		}else if(method.equalsIgnoreCase("POST")) {
			doPost(hreq,hresp);
		}
		
		
	}

	protected void doPost(HttpServletRequest hreq, HttpServletResponse hresp) throws ServletException, IOException {//为了让子类可用,我把私有改为受保护的了
		
		
	}

	protected void doGet(HttpServletRequest hreq, HttpServletResponse hresp) throws ServletException, IOException {
		
		
	}
}

应用:继承MyHttpServlet*

public class GetPostMyHttpServlet extends MyHttpServlet{
	private static final long serialVersionUID = 1L;
	//重定两个方法,如果是get请求,就在doGet中做事,反之是在doPost中做事

	@Override
	protected void doPost(HttpServletRequest hreq, HttpServletResponse hresp) throws ServletException, IOException {
		
	}

	@Override
	protected void doGet(HttpServletRequest hreq, HttpServletResponse hresp) throws ServletException, IOException {
		String username=hreq.getParameter("username");
		String password = hreq.getParameter("password");
		//比较浏览器提交表单数据与web.xml中定义的全局参数数据比较,如果相等,则login success,否则login failed!
		if(username.equals(getServletConfig().getServletContext().getInitParameter("username")) &&
				password.equals(getServletConfig().getServletContext().getInitParameter("password")))
			hresp.getWriter().println("Login success!");
		else
			hresp.getWriter().println("login failed!!");
	}
}

      Tomcat给我们提供了一个简化的实现,HttpServlet,真正开发的时候我们用的就是将每个自定义的Servlet继承这个类。然后重写覆盖doGet方法或doPost方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊少文

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值