Servlet之表单提交,数据查询,文件上传

it2022-05-05  97

    一个Web程序中几乎总是包含一个或者多个HTML表单,供用户输入。现在不同于之前在frontpage中直接编写HTML文件,而是在IDEA中,将HTML从一个Servlet发送到浏览器。在这里只实现简单功能。     首先,不需要手动部署Tomcat,那么在新建项目时需要选择Web Application,这样才能自动生成web.xml。 接下来,写FormServlet类:

import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /*将HTML从一个Servlet发送到浏览器。表单视图*/ public class FormServlet extends HttpServlet { /*HttpServlet的子类至少必须重写一个方法,这里重写的是doGet方法*/ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter writer=resp.getWriter(); writer.append("<html>") .append("<head>") .append("<meta charset='UTF-8'>") .append("<title>Form</title>") .append("<head>") .append("<body>") .append("<form method='POST' action=/form>") .append("请输入姓名:") .append("<input name='name' type='text' value=''/>") .append("<input type='submit' value-'提交'>") .append("</form>") .append("</body>") .append("</html>"); } }

    这里的form的action,即表单提交的目标URL——写的是action="/form",也就是我们后面配置web.xml中的URL。也可以写成action=" ",空即表示提交到本页面,相当于刷新。(我感觉两种都相当于刷新,这时点“提交按钮”,相当于又一次HTTP请求,所以接下来写的doPOST方法才起作用。) 接下来,需要在web.xml中配置servlet:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>FormServlet</servlet-name> <servlet-class>FormServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FormServlet</servlet-name> <url-pattern>/form</url-pattern> </servlet-mapping> </web-app>

然后运行,在浏览器中访问:

接下来,写入提交表单的处理逻辑:

@Override protected void doPost(HttpServletRequest req,HttpServletResponse resp) throws IOException {String name=req.getParameter("name"); resp.setContentType("text/html;charset=UTF-8"); PrintWriter writer=resp.getWriter(); writer.append("<html>") .append("<head>") .append("<meta charset='UTF-8'>") .append("<title>Form</title>") .append("</head>") .append("<body>") .append("<h1>") .append("欢迎") .append(name) .append("</h1>") .append("</body>") .append("</html>"); }

          form表单中的所有参数可在转向后的页面或者类中通过getParameter()方法获得。 浏览器显示结果为:

以上便完成了简单的表单提交,接下来,实现数据查询。

import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class QueryServlet extends HttpServlet { private Map<String, String> cityMap = new HashMap<String, String>(); private Map<String, List<String>> scenicSpot = new HashMap<String, List<String>>(); @Override public void init() throws ServletException { super.init(); List<String> xian = new ArrayList<>(); xian.add("华清池"); xian.add("兵马俑"); xian.add("大雁塔"); scenicSpot.put("Xi'an", xian); cityMap.put("Xi'an", "西安"); List<String> baoji = new ArrayList<String>(); //baoji.add("太白山"); baoji.add("法门寺"); baoji.add("关山牧场"); scenicSpot.put("BaoJi", baoji); cityMap.put("BaoJi", "宝鸡"); List<String> xianyang = new ArrayList<String>(); xianyang.add("乾陵"); xianyang.add("袁家村"); scenicSpot.put("XianYang", xianyang); cityMap.put("XianYang", "咸阳"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { String city = req.getParameter("city"); List<ScenicSpot> scenicSpotstoArrayList = new ArrayList<ScenicSpot>(); if(city==null||city.length()==0) {for(Map.Entry<String,List<String>> entry:scenicSpot.entrySet()) { String citykey=entry.getKey(); List<String> scenics=entry.getValue(); for(String item:scenics) { ScenicSpot scenicSpotcla=new ScenicSpot(); scenicSpotcla.setCity(cityMap.get(citykey)); scenicSpotcla.setName(item); scenicSpotstoArrayList.add(scenicSpotcla); } } } else {List<String>scenics=scenicSpot.get(city); if(scenics==null) {scenics=new ArrayList<String>();} for(String item:scenics) {ScenicSpot scenicSpotcla=new ScenicSpot(); scenicSpotcla.setCity(cityMap.get(city)); scenicSpotcla.setName(item); scenicSpotstoArrayList.add(scenicSpotcla);} } resp.setContentType("text/html;charset=UTF-8"); PrintWriter writer=resp.getWriter(); writer.append("<!DOCTYPE html>\n"+ "<html lang=\"en\">+\n"+ "<head>\n"+ "<meta charset=\"UTF-8\">\n"+ "<title>景点</title>\n"+ "</head>\n"+ "<body>\n"+ "<table>\n"+ "<thead>\n"+ "<tr>\n"+ "<td>编号</td>\n"+ "<td>所在城市</td>\n"+ "<td>景点名称</td>\n"+ "</tr>\n"+ "</thead>\n"+ "<tbody>"); int id=1; for(ScenicSpot pot:scenicSpotstoArrayList) {writer.append("<tr>") .append("<td>") .append(String.valueOf(id)) .append("</td>") .append("<td>") .append(pot.city) .append("</td>") .append("<td>") .append(pot.name) .append("</td>") .append("</tr>"); id=id+1; } writer.append("</tbody>\n"+ "</table>\n"+ "</body>\n"+ "</html>"); } public class ScenicSpot {private String city; private String name; public void setCity(String city) { this.city = city; } public void setName(String name) { this.name = name; } } }

     第一步,准备静态数据,拟实现城市与城市的景点对应的查询。对这种具有映射关系(key-value)的数据进行存储,考虑到Map集合。     首先,需要两个Map集合,一个用来映射如:城市“Xi’an”和该城市的中文“西安”;另一个用来映射城市和景点,如“Xi’an”和“华清池”,“大雁塔”,“兵马俑”。因此,这两个Map集合的定义分别是Map<String,String>cityMap和Map<String,List>scenicSpot。并通过Map类的put方法存储西安、宝鸡和咸阳城市的以上两组映射信息。     接下来,新建一个公共类 ScenicSpot,它具有city和name(即景点名)属性,并为其构造setter方法,用于存储Map中的每一个映射。再新建一个List集合scenicSpotstoArrayList,把ScenicSpot类new的所有对象放在这个集合中。      如果从浏览器传来的“city”属性为空,(实现从浏览器取得“city”属性的代码将在稍后展示),那么我们就取得所有映射并输出。在Map中有entrySet()方法,它会返回Set<Map.Entry<k,v>>,(Map.Entry是Map内部的一个接口。该接口中提供了getkey()和getvalue()方法),对这个Set中的元素进行foreach()遍历,调用getkey()和getvalue()方法,比如,对Set集合中的第一个Map.Entry元素——“Xi’an"与“华清池”,“大雁塔”,“兵马俑”,调用getkey()方法即可获得"Xi’an”,将它赋给String citykey; 调用getvalue()方法即可获得“华清池”,“大雁塔”,“兵马俑”,将这三个景点放入 List scenics中。      再通过对集合scenics中元素的遍历,为每一个元素创建ScenicSpot类对象,将每个元素赋给该类的name属性(即景点名),并将之前取得的citykey,先通过Map的get()方法,得到key对应的value,即城市的中文名,并将中文名赋给该类的city属性。最后,将这个对象通过List的add()方法加入,这样scenicSpotstoArrayList集合中放的元素便是一个个映射:“西安”与“华清池”,“西安”与“大雁塔”,“西安”与“兵马俑”······     以上便是.java代码部分的逻辑简述,映射已经就绪,接下来是要解决如何在浏览器上输出的问题。用HTML语言将城市与对应景点输出,并加以编号。在此提供Frontpage下的HTML效果如下:

配置web.xml文件:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>FormServlet</servlet-name> <servlet-class>FormServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FormServlet</servlet-name> <url-pattern>/form</url-pattern> </servlet-mapping> <servlet> <servlet-name>QueryServlet</servlet-name> <servlet-class>QueryServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>QueryServlet</servlet-name> <url-pattern>/query</url-pattern> </servlet-mapping> </web-app>

    在浏览器中显示的结果为: 接着,试着写一个查询界面,实现对单个城市的查询。 加上一下代码:

@Override protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter writer=resp.getWriter(); writer.append("<html>") .append("<head>") .append("<meta charset='UTF-8'>") .append("<title>CityQuery</title>") .append("</head>") .append("<body>") .append("<form action='/query'>") .append("请输入城市") .append("<input name='city' type='text' />") .append("<input type='submit' value='查询'/>") .append("</form>") .append("</body>") .append("</html>"); }

浏览器显示结果为: 点击查询按钮后,浏览器显示结果为: 则实现了单个城市的查询。也是在这个例子中,我对表单提交有了新的理解,原来的意思是它会去调用相应servlet的doPost方法**,(默认method的属性值是GET)**而action=/form指向的便是要调用 的servlet。所以这里的method值不能胡写,是要与下文完成表单处理逻辑的doPost或者doGet相对应的。于是我想到,把doPost写在前面,处理查询输入页面,将form的method属性设置成Get,在后面的doGet方法中处理查询输出页面。结果浏览器显示的结果为: 可以发现浏览器不会从前面的doPost()开始,而是直接进入doGet()的。即使我将form的method改为POST也不会进入输入页面。网上的说法是, 以下是get方式:

form默认的提交方式通过一个超链访问某个地址如果在地址栏直接输入某个地址ajax指定使用get方式的时候 因此,当我在地址栏输入http://localhost:8080/query时,其实就已经使用get方式了,当浏览器使用get方式提交数据的时候,servlet需要提供doGet()方法。这样看来,以后需要把doGet()写在前面,并且在form的method中赋值“POST”,在后面写doPost()。      最后,在Web应用中除了处理表单提交以外,还有一个特殊的提交内容就是文件,比如:上传图片,音频,视频。本文的最后需要实现文件上传的功能。     首先,写一个静态页面。     接下来,实现上传文件servlet,接收文件并且存储。

最新回复(0)