这里写目录标题
core核心标签,逻辑标签
其它标签
redirect标签
用来实现请求重对象功能,此标签可以重定向到本应用内部资源也可以定位到服务器之外的其它资源;通过子标签param可以是心啊查询参数传递
url属性:重定向目标资源路径
context属性:重定向目标url资源所在上下文名称
index.jsp
<a href="redirect.jsp?location=2.jsp">点击进入</a>
redirect.jsp
<body>
<c:if test="${param.location ne null}">
<c:redirect url="${param.location}">
<c:param name="userName" value="liang"></c:param>
</c:redirect>
</c:if>
</body>
2.jsp
<body>
${param.userName}
</body>
自定义标签
组成
开发过程
1、去欸的那个标签功能
2、编写实现标签功能类(特殊的Java类)
3、编写标签库描述文件(.tld后缀的xml文件)
4、在页面中测试标签
DateFormat.java
package com.customtag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatTag extends TagSupport {
private Date target;// 对应标签的target属性
private String format;// 对应标签的format属性
private static String DATE_BASE = "date";//默认格式
private static String DATE_FULL = "datefull";
private static String TIME= "time";
private static String TIME_FULL= "timefull";
@Override
public int doStartTag() throws JspException {
PrintWriter out = null;
try {
out = this.pageContext.getResponse().getWriter();
} catch (IOException e) {
e.printStackTrace();
}
if(format==null || format.equals("")){
String dateStr = new SimpleDateFormat("yy/M/d").format(target);
out.print(dateStr);
}else if(format.equals(DATE_BASE)){
String dateStr = new SimpleDateFormat("yy/M/d").format(target);
out.print(dateStr);
}else if(format.equals(DATE_FULL)){
String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(target);
out.print(dateStr);
}else if(format.equals(TIME)){
String dateStr = new SimpleDateFormat("h:m:s").format(target);
out.print(dateStr);
}else if(format.equals(TIME_FULL)) {
String dateStr = new SimpleDateFormat("hh:mm:ss").format(target);
out.print(dateStr);
}else{
try{
throw new Exception("format有效属性值为" + DATE_BASE + DATE_FULL + TIME + TIME_FULL);
}catch (Exception e){
e.printStackTrace();
}
}
return super.doStartTag();
}
@Override
public int doEndTag() throws JspException {
return DateFormatTag.EVAL_PAGE;
}
public Date getTarget() {
return target;
}
public void setTarget(Date target) {
this.target = target;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
}
customTag.tld
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>custom_RT</short-name>
<uri>http://java.sun.com/jstl/core</uri>
<display-name>JSTL core</display-name>
<description>JSTL 1.0 core library</description>
<validator>
<validator-class>
org.apache.taglibs.standard.tlv.compat.JstlELCoreTLV
</validator-class>
<init-param>
<param-name>expressionAttributes</param-name>
<param-value>
out:value
out:default
out:escapeXml
if:test
import:url
import:context
import:charEncoding
forEach:items
forEach:begin
forEach:end
forEach:step
forTokens:items
forTokens:begin
forTokens:end
forTokens:step
param:encode
param:name
param:value
redirect:context
redirect:url
set:property
set:target
set:value
url:context
url:value
when:test
</param-value>
<description>
Whitespace-separated list of colon-separated token pairs
describing tag:attribute combinations that accept expressions.
The validator uses this information to determine which
attributes need their syntax validated.
</description>
</init-param>
</validator>
<tag>
<name>date</name>
<tag-class>com.customtag.DateFormatTag</tag-class>
<body-content>empty</body-content>
<description>
转换date对象为字符串格式
</description>
<attribute>
<name>target</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.util.Date</type>
</attribute>
<attribute>
<name>format</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
</attribute>
</tag>
</taglib>
index.jsp
<%@ page import="java.util.Date" %>
<%@ taglib prefix="m" uri="/WEB-INF/tag/customTag.tld" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
Date date = new Date();
%>
<m:date target="<%=date%>"/><br/>
<m:date target="<%=date%>" format="datefull"/><br>
<m:date target="<%=date%>" format="time"/><br>
<m:date target="<%=date%>" format="timefull"/><br>
<%--<%– <m:date target="<%=date%>" format="timdffdsadadfll"/><br>–%> 报错提示--%>
</body>
</html>
结果:
不知道为什么,没有换行……
AOP编程
AOP编程:(Aspect Oriented Programming)面向切面编程,将主要核心业务与非主流业务分开处理,降低代码耦合性,提高重用性
优势:
设计核心业务与非核心业务分离
有效降低代码的耦合度复杂度,构建松耦合程序模式
提供可重用性更高更易于维护的系统
设计灵活可插拔式的架构
开发关注点更集中某一方面
文件的上传和下载
fileupload组件实现web文件上传
使用Apache的fileupload开源组件,commons-fileupload.jar和commons-io.jar是核心API
DiskFileItemFactory是FFileItemFactory接口默认实现,此类将请求消息实体中的每一个项目封装成单独的DiskFileItem(FileItem接口实现)
ServletFileUpload类是Apache文件上传组件处理文件上传的核心高级类,它的最核心功能是使用parseRequest(HttpServletRequest)方法将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象。然后以List列表形式返回
构造方法:
public ServletFileUpload()
public ServletFileUpload(FileItemFactory fileItemFactory)
主要方法
将form表单项转换为FileItem实例并存储到List中返回
ListparseRequest(javax.servlet.HttpServletTequest req)
设置所有上传数据的最大上限,以字节为单位
setSizeMax(long sizeMax)
设置单个上传文件的最大上限
setFileSizeMax(long fileSizeMax)
设置编码格式
setHeaderEncoding(String encoding)
DiskFileItem类是FileItem接口的实现类,用来封装单个表单字段元素的数据,对于文件上传而言只处理实际是File对象的写入操作
主要方法:
boolean isFormFileld() 判断是文件还是普通表单元素
String getName() 获得文件上传字段中的文件名
String getFileName() 获取表单字段元素描述头的name属性值
void write(File file) 写入目标文件
String getContentType() 得到上传文案缉拿的类型字符串描述
boolean isInMemory() 判断文件是存储在内存还是临时文件中
void delete() 用来清空FileItem类对象中存放的主体内容
InputStream getInputStream() 得到文件流
long getSize() 返回该上传文件的大小(字节数)
web同步文件上传表单要求
<form>元素method属性值必须为post
<form>元素enctype属性值必需为multipart/form_data
上传目标文件以<input type=“file” name=“uploadFile” />文件域表示
例子:实现文件上传
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="/myweb/ful" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="file1"/><br>
文件2:<input type="file" name="file2"/><br>
年龄:<input type="text" name="age" value="23"/><br>
<input type="submit" value="提交">
</form>
</body>
</html>
servlet
package com.controller;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
@WebServlet(name = "FileUploadServlet")
public class FileUploadServlet extends HttpServlet {
private String uploadSaveDir;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
uploadSaveDir = this.getServletContext().getRealPath("/WEB-INF/uploadfiles/");
System.out.println("文件保存的真实目录:" + uploadSaveDir);
/*设置默认属性设置的磁盘文件项工厂对象*/
DiskFileItemFactory factory = new DiskFileItemFactory();
System.out.println("默认文件保存的临时文件目录是:" +System.getProperty("java.io.tmpdir"));
System.out.println(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD);
/*构建ServletFileUpload组件*/
ServletFileUpload fileUpload = new ServletFileUpload();
//设置使用的FileItemFactory
fileUpload.setFileItemFactory(factory);
//设置相关属性
fileUpload.setFileSizeMax(1024*10);
fileUpload.setSizeMax(1024*100);
fileUpload.setHeaderEncoding("utf-8");
/*获取FileItemFactory所有文件项 FileItem */
List<FileItem> itemList = null;
try {
itemList = fileUpload.parseRequest(req);
for(FileItem item:itemList){
if("".equals(item.getName())){
continue;
}
/*判断是文字表单字段还是文件组件*/
if(!item.isFormField()){//如果是文件组件(不是表单字段)
String fileName = item.getName();//获取文件的上传名称
System.out.println(uploadSaveDir + new Date().getTime()+fileName);
File target = new File(uploadSaveDir + new Date().getTime()+fileName);//避免文字重复而导致文件的覆盖
System.out.println("文件名称:" + fileName);
System.out.println("字段名称:" + item.getFieldName());
System.out.println("文件大小:" + item.getSize());
System.out.println("文件类型:" + item.getContentType());
item.write(target);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
控制台
tip:在获取文件路径的时候,会得到/out的路径,而在点击上传的时候,因为这个out路径找不到,报404,花了点时间,最终把以下位置改了:
文件下载
获取下载连接请求的文件id参数
根据id查找目标文件建立文件对象,判断文件是否存在
基于目标文件建立输入流读取文件到内存
设置响应头内容,告知浏览器是文件流响应方式
输出文件到客户端浏览器,处理异常关闭文件流
例子:
首先将用户要下载的资源放到文件夹当中
download.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>下载列表</h2>
<a href="/myweb/download?fileId=faxian.png">图片1</a><br>
<a href="/myweb/download?fileId=无标题.png">图片2</a><br>
<a href="/myweb/download?fileId=不存在的图片.png">不存在的图片</a>
</body>
</html>
servlet
package com.controller;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DownloadServlet extends HttpServlet {
private String dir;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("fileId");
dir = getServletContext().getRealPath("/WEB-INF/downloads/");//获取下载链接的文件id路径
ServletOutputStream output = null;
//建立下载的目标文件
File target = new File(dir + id);
InputStream in = null;
if(target.exists()){
in = new FileInputStream(target);
// 设置文件临时存储的缓冲区
byte[] datas = new byte[12400];
int count = 0;//读取字节的记数器
//设置响应头内容
resp.setHeader("content-disposition",
"attachment;filename=" + URLEncoder.encode(target.getName(), "UTF-8"));
output = resp.getOutputStream();//获取响应给客户端的文件输出流
/*读取文件到缓冲区,响应发送输出流到客户端浏览器*/
while ((count = in.read(datas,0,datas.length)) > 0){
output.write(datas,0,count); //输入到客户端
}
output.flush();
output.close();
in.close();
}else {
//如果文件不存在
resp.sendRedirect("error.jsp");
}
}
}
结果;
点击,下载成功
MVC模式
MVC模式:
Model View Controller,是模型-视图-控制器的缩写,一种软件设计典范,用业务逻辑数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑
MVC被广泛用于映射传统的输入、处理和输出功能在一个逻辑的图形花用户界面的结构设计中
Java Web最初的MVC模式
Model层:用Java Bean作为模型层组件,它是业务数据处理核心,通常与底层存储库进行交互
View层:用Jsp实现动态数据的视图显示组件,View视图的数据间接来源于Model模型的业务数据
Controller层:用Servlet实现处理用户请求并做出响应,Servlet是将View和Model强行分离的控制组件
部署发布java web到Tomcat服务器
在Tomcat找到bin下的startup.bat,双击
浏览器输入http://localhost:8080/manager/html
用户名和密码问题可以看这篇博客
找到以下位置,将要发布的程序路径填上
要发布的是web文件夹,里面有以下文件(idea下,eclipse会不同)
注意,这个context路径要与idea里设置的一致,不然会404:
点击部署后:
点击上图箭头所指的位置,就可以进入程序了…
使用war包的方式部署
如何将代码打包成war包,可以看这里
同样的,要注意命名,要和idea里设置的一样,我这里命名了myweb
部署成功:
利用本地部署
没有成功,以后找到出错原因再添加进去