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》

《2》

《3》配置maven

《4》下图中,爆红,是因为,sts开发工具的Dynamic Web Module模式版本太低了,现在我们都3.x了,这里还是2.5,如下面第二图所示。


处理办法:
先去掉那个勾选,再点应用(apply),选勾选3.1版本,同时到下面点击’Further configuration available…',我们勾选Generate web.xml。。。,让项目自建web.xml文件。

《5》,build path,即增加jdk库,apache库

一个自已写的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自动下载。
-
新建一个maven工程 maventest

-
导包pom.xml
<dependencies>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.9</version>
<type>pom</type>
</dependency>
</dependencies>
- 建一个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
...

-
构造方法,最先被执行,构造方法被执行意味着创建新的实例,且只会被执行一次,意味着Servlet是单例的,在整个Servlet容器中每个具体的Servlet实现类都只有一个实例!
-
init:构造方法之后,马上被执行,且只执行一次,作用是做初始化,虽然构造方法也能做初始化操作,但init(ServletConfig arg0)是带了参数回来的,作用更大,后面在具体讲这个参数。
-
service:被多次调用,每次在浏览器刷新请求都会调用一次service方法,实际用于对请求的响应。
-
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
-
GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;这些数据都是键值对的格式。
POST提交:把提交的数据放置在是HTTP包的包体中。
因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变 -
传输数据的大小:首先声明:HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。
但是部分浏览器对URL长度有限制。
GET:特定浏览器和服务器对URL长度有限制,例如 IE对URL长度的限制是2083字节(2K+35)。
POST:由于不是通过URL传值,理论上数据不受限。 -
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方法。
835

被折叠的 条评论
为什么被折叠?



