文章目录
一、关于转发和重定向
面试常考题:转发(forward)和重定向(redirect)的区别:
1.1 简单回答
- 转发的特点:forward
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象来共享数据
- 重定向的特点:redirect
- 地址栏发生变化
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求。不能使用request对象来共享数据
1.2 详细说明
1.2.1 转发(forward)
是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,因为这个跳转过程实在服务器实现的,并不是在客户端实现的所以客户端并不知道这个跳转动作,所以它的地址栏还是原来的地址。
1.2.2 重定向(redirect)
是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL。
1.2.3 转发(forward)和重定向(redirect)的区别
1.2.3.1 从地址栏来说
转发(forward):转发地址栏路径不变,转发只能访问当前服务器下的资源,转发是一次请求,可以使用request对象来共享数据
重定向(redirect):地址栏发生变化,重定向可以访问其他站点(服务器)的资源,重定向是两次请求。不能使用request对象来共享数据
1.2.3.2 从数据共享来说
转发(forward):转发页面和转发到的页面可以共享request里面的数据.
重定向(redirect):不能共享数据
1.2.3.3 从运用地方来说
转发(forward):一般用于用户登陆的时候,根据角色转发到相应的模块.
重定向(redirect):一般用于用户注销登陆时返回主页面和跳转到其它的网站等
1.2.3.4 从效率来说
转发(forward):高
重定向(redirect):低
1.3 代码演示
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo1...");
// 重定向是两次请求,不能使用request对象来共享数据
request.setAttribute("msg", "response");
//转发(是服务器之间的交流,相对路径即可)
// request.getRequestDispatcher("/responseDemo2").forward(request,response );
/*//重定向方法的实现
//1.设置状态码为302
response.setStatus(302);
//2.设置响应头location
response.setHeader("location","/day4/responseDemo2" );*/
//设置重定向方法的简化
//获取动态虚拟目录
String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/responseDemo2");
// response.sendRedirect("https://www.baidu.com");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response );
}
}
二、文件传输中IO中读写操作
2.1 IO的分类
①.根据数据的流向分为:输入流和输出流。
- 输入流 :把数据从
其他设备
上读取到内存
中的流。 - 输出流 :把数据从
内存
中写出到其他设备
上的流。
②.根局数据的类型分为:字节流和字符流。
- 字节流 :以字节为单位,读写数据的流。
- 字符流 :以字符为单位,读写数据的流。
2.2 顶级父类们
输入流(读) | 输出流(写) | |
---|---|---|
字节流 | 字节输入流 InputStream | 字节输出流 OutputStream |
字符流 | 字符输入流 Reader | 字符输出流 Writer |
三、日期转换问题
pattern为所指定的转换格式:一般为:yyyy-MM-dd HH:mm:ss
3.1 代码参考段
/**
* 日期转换的工具类
*/
public class DateUtils {
//日期转字符串(patt为所指定的转换格式:一般为:yyyy-MM-dd HH:mm:ss)
public static String dateToString(Date date,String patt) {
SimpleDateFormat sdf = new SimpleDateFormat(patt);
String format = sdf.format(date);
return format;
}
//字符串转为日期
public static Date stringToDate(String str,String patt) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(patt);
Date date = sdf.parse(str);
return date;
}
}
四、状态码的问题
响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
状态码都是3位数字
4.1 分类
1. 1xx:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
2. 2xx:成功。代表:200 //ResponseEntity.ok(categoryList);或者ResponseEntity.status(HttpStatus.CREATED).build();
3. 3xx:重定向。代表:302(重定向),304(访问缓存)
4. 4xx:客户端错误。
* 代表:
* 400:参数不合法(参数配置错误) //ResponseEntity.badRequest().build();
* 403 请求路径的权限不够
* 404(请求路径没有对应的资源) //ResponseEntity.notFound().build();
* 405:请求方式没有对应的doXxx方法
5. 5xx:服务器端错误。代表:500(服务器内部出现异常)
4.2 响应消息:服务器端发送给客户端的数据
- 响应行
1. 组成:协议/版本 响应状态码 状态码描述
2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。 - 响应头:
- 格式:头名称: 值
- 常见的响应头:
- Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
- Content-disposition:服务器告诉客户端以什么格式打开响应体数据
- 值:
- in-line:默认值,在当前页面内打开
- attachment;filename=xxx:以附件形式打开响应体。文件下载
- 响应空行
- 响应体:传输的数据
五、相对路径和绝对路径
一般的jsp中页面路径的写法:${pageContext.request.contextPath}/pages/product-add.jsp
5.1 相对路径:通过相对路径不可以确定唯一资源
- 如:./index.html
- 不以/开头,以.开头路径
- 规则:找到当前资源和目标资源之间的相对位置关系
./:当前目录
…/:后退一级目录
5.2 绝对路径:通过绝对路径可以确定唯一资源
- 如:http://localhost/day15/responseDemo2 /day15/responseDemo2
- 以/开头的路径
- 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
建议虚拟目录动态获取:request.getContextPath()
, 重定向…
给服务器使用:不需要加虚拟目录
转发路径
六、中文乱码问题
6.1 页面的几种编码属性
pageEncoding="UTF-8" jsp页面编码,jsp文件本身的编码
contentType="text/html; charset=UTF-8" web页面显示的编码,jsp页面输出流在浏览器中显示的编码
----web界面的输入编码,就是输入框中输入的字体编码(指下面的meta)
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6.2 get提交方式乱码处理
(一般是由于tomcat引起的,所以需要设置tomcat的编码)改tomcat中server.xml中的配置,加上一个 URIEncoding=”utf-8” 如下所示:
<Connector connectionTimeout="20000" port="8000" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>
6.3 post提交方式乱码处理(在web.xml中设置编码过滤器)
<!-- 字符过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
以上使用的过滤器在使用时有一定的要求,支持post提交方式,该过滤器是servlet自带的,只需配置即可,相当于前端控制器在分发请求后,处理器在接受请求时添加了request.setCharacterEncoding(“UTF-8”);若为get请求则此配置不起任何作用,需要修改tomcat文件(步骤2)
6.4 数据库连接字符串指定编码
jdbc.url=jdbc:mysql://localhost:3306/student?characterEncoding=UTF-8
- 在springCloud项目中遇到的乱码:解决方案(在service层application.yml配置)
url: jdbc:mysql://localhost:3306/leyou?useUnicode=true&characterEncoding=utf8
6.5 项目中遇到的乱码
6.5.1 @RequestParam属性的乱码
- 解决方法:直接在controller类中进行设置就可以了
String cityName = new String(cityName.getBytes("ISO-8859-1"),"utf-8");
request,response请求页面乱码设置
- PrintWriter pw = response.getWriter();获取的流的默认编码是ISO-8859-1
- 设置该流的默认编码
- 告诉浏览器响应体使用的编码
-
简单的形式,设置编码,是在获取流之前设置
response.setContentType(“text/html;charset=utf-8”); -
代码参考段
@WebServlet("/responseDemo3")
public class ResponseDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取流对象之前,设置流的默认编码:ISO-8859-1 设置为:GBK
// response.setCharacterEncoding("utf-8");
//告诉浏览器,服务器发送的消息题数据的编码,建议浏览器使用该编码解码
// response.setHeader("content-type","text/html;charset=utf-8" );
//简单的形式,设置编码(因为每次修改的响应头信息content-type都是相同的)
response.setContentType("text/html;charset=utf-8");
//1.获取字符输入流
PrintWriter pw = response.getWriter();
//2.输出数据
// pw.write("<h1>Hello Response!</h1>");
pw.write("你好 Response!");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response );
}
}
七、文件下载
7.1 传统方式下载
- 总实现代码
/*
文件下载需求:
1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载
*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取请求参数,文件名称
String filename = request.getParameter("filename");
//2使用字节输入流加载文件进内存
//2.1找到文件服务器路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/1.jpg");
//2.2使用字节流相关联
FileInputStream fis = new FileInputStream(realPath);
//3.设置response的响应头
//3.1设置响应头类型content-type
String mimeType = servletContext.getMimeType(filename); //获取文件的mime类型
response.setHeader("content-type",mimeType);
//3.2设置响应头的打开方式content-disposition
//*解决中文文件名问题
//1.获取user-agent请求头
String agent = request.getHeader("user-agent");
//2.使用工具方法编码文件名即可
filename = DownLoadUtils.getFileName(agent, filename);
response.setHeader("content-disposition", "attachment;filename="+filename);
//4.将输入流的数据写到输出流中
ServletOutputStream sos = response.getOutputStream();
byte[] buff = new byte[1024 * 8];
int len = 0;
while ((len = fis.read(buff)) != -1) {
sos.write(buff,0,len);
}
fis.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response );
}
}
- 判断浏览器的工具类DownLoadUtils
public class DownLoadUtils {
public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
7.2 SpringMVC中的文件上传(传统方式和SpringMVC方式)
- 可以直接参考以下链接的文章
https://blog.csdn.net/qq_43369851/article/details/102565430
八、Linux中常用命令
Linux命令 | 作用 |
---|---|
Ctrl + Alt | 快速清屏 |
cd | 切换目录 |
pwd | 查看用户当前的目录 |
cd. . | 回到上一级目录 |
cd ~ | 进入用户主目录的绝对路径名 |
ls | 显示文件或目录信息 |
ll | (ls -l)的别名,作用:显示当前目录下文件详细信息 |
mkdir | 在当前目录下创建一个空目录 |
cp | 复制文件或目录 |
rm | 删除文件或目录 |
cat | 查看文本文件内容 |
mv | 移动文件或目录、文件或目录改名 |
find | 查找文件或目录 |
chmod | 修改文件权限(例如:chmod 777 file.java //file.java的权限-rwxrwxrwx,r表示读、w表示写、x表示可执行) |
鼠标右击Linux页面 | 粘贴操作 |
以斜线(/)开头 | 到文件位置的完整说明,任何时候指定文件都可以使用 |
不以斜线(/)开头 | 指定相对于你当前工作目录而言的位置 |
九、ssm项目中所遇问题
9.1 数据库的模糊查询(注解方式)
9.1.1 在mysql中的语句
select * from user where username like concat('%',#{username},'%');
9.1.2 在oracle中的语句
-- 第一种
select * from students where studentName like concat(#{studentName},'%');
-- 第二种(***)
@Select("select * from students where studentName like '%' || #{studentName} || '%'")
@Select("select * from device where roomNum like '%'||#{searchInfo}||'%' or brand like '%'||#{searchInfo}||'%'")
9.2 进行修改产品信息
//伪代码块
//修改产品信息(第一步:查询产品信息(可修改信息))
@RequestMapping("/updateResearch.do")
public ModelAndView updateProductById(@RequestParam(name = "id",required = true)String productId) throws Exception{
ModelAndView mv = new ModelAndView();
Product product = productService.findById(productId);
mv.addObject("product",product);
mv.setViewName("product-edit");
return mv;
}
//修改产品信息(第二步:拿到表单提交的信息,进行保存)
@RequestMapping("/update.do")
public String update(Product product) throws Exception{
productService.updateProduct(product);
return "redirect:findAll.do";
}
//dao层
//修改产品信息
@Update("update product set productNum = #{productNum},productName = #{productName},cityName = #{cityName},departureTime = #{departureTime},productPrice = #{productPrice},productDesc = #{productDesc},productStatus = #{productStatus} where id = #{id}")
void updateProduct(Product product) throws Exception;
9.3 删除、复选框全选功能的实现
//删除商品
@RequestMapping("/delete.do")
public String batchDeletes(@RequestParam(name = "delitems")String delitems) {
String[] strs = delitems.split(",");
for (int i = 0; i < strs.length; i++) {
try {
String productId = strs[i];
System.out.printf("订单编号为:"+productId);
productService.delProduCtById(productId);
} catch (Exception e) {
}
}
return "redirect:findAll.do";
}
//删除产品
@Delete("delete from product where id = #{productId}")
void delProduCtById(String productId);
//前台jsp代码
//在删除按钮中添加属性
onclick="batchDeletes()"
<script>
//进行删除复选框
function batchDeletes(){
//判断至少写了一项
var checkedNum = $("input[name='subcheck']:checked").length;
if(checkedNum==0){
alert("请至少选择一项!");
return false;
}
if(confirm("确定删除所选项目?")){
var checkedList = new Array();
$("input[name='subcheck']:checked").each(function(){
checkedList.push($(this).val());
});
$.ajax({
type:"Post",
url:"http://localhost:8080/hugong_ssm_web/product/delete.do",
data:{"delitems":checkedList.toString()},
datatype:"html",
success:function(data){
/*$("[name='checkbox2']:checkbox").attr("checked",false);
location.reload();//页面刷新*/
art.dialog.tips('删除成功!');
},
error:function(data){
art.dialog.tips('删除失败!');
}
});
}
}
</script>
//复选框全选的操作
<script>
function changePageSize() {
//获取下拉框的值
var pageSize = $("#changePageSize").val();
//向服务器发送请求,改变没页显示条数
location.href = "${pageContext.request.contextPath}/product/findAll.do?page=1&size="
+ pageSize;
}
$(document).ready(function() {
// 选择框
$(".select2").select2();
// WYSIHTML5编辑器
$(".textarea").wysihtml5({
locale: 'zh-CN'
});
});
// 设置激活菜单
function setSidebarActive(tagUri) {
var liObj = $("#" + tagUri);
if (liObj.length > 0) {
liObj.parent().parent().addClass("active");
liObj.addClass("active");
}
}
$(document).ready(function() {
// 激活导航位置
setSidebarActive("admin-datalist");
// 列表按钮
$("#dataList td input[type='checkbox']").iCheck({
checkboxClass: 'icheckbox_square-blue',
increaseArea: '20%'
});
// 全选操作
$("#selall").click(function() {
var clicks = $(this).is(':checked');
if (!clicks) {
location.reload();//页面刷新
$("#dataList td input[type='checkbox']").iCheck("uncheck");
} else {
$("#dataList td input[type='checkbox']").iCheck("check");
}
$(this).data("clicks", !clicks);
});
});
</script>
9.4 搜索框功能的实现
代码实现
<div class="has-feedback">
<input type="text" id="search_input" class="form-control input-sm" placeholder="请输入搜索信息">
<a href="javascript:click_button();" id="search-button">
<div style="padding-left: 150px ">搜索</div>
</a>
</div>
<script>
//定义函数
function click_button() {
//获取输入框的值
var cityName = $("#search_input").val();
//跳转路径http://localhost/travel/route_list.html?cid=5,拼接上rname
// var cid = getParameter("cid");
location.href = "http://localhost:8080/hugong_ssm_web/product/findByCityName.do?cityName="+cityName+"&page=1&size=4";
}
</script>
十、java字符串的常用方法
java常见的方法函数:
作用 | 方法名 |
---|---|
字符串比较 | compareTo、compareToIgnoreCase |
字符串查找 | indexOf、lastIndexOf |
字符串替代 | replace、replaceAll |
字符串反转 | reverse |
字符串转变大小写 | toUpperCase、toLowerCase |
去掉首尾空格 | trim |
是否包含某字符/字符串 | contains |
返回指定位置字符 | charAt |
代码演示及其运行结果:
public static void main(String args[]){
String str1 = "Hello World";
String str2 = "Hello World";
String str3 = "hello world";
String str4 = " hello world ";
//字符串比较字符串比较compareTo(返回的是int),0相等,复数小于,正数大于
System.out.println("r1 : " + str1.compareTo(str2));
//字符串比较字符串比较compareTo(返回的是int),0相等,复数小于,正数大于
System.out.println("r2 : " + str1.compareTo(str3));
//字符串比较compareToIgnoreCase,忽略大小写。0相等,复数小于,正数大于
System.out.println("r3 : " + str1.compareToIgnoreCase(str3));
//字符串查找indexOf,返回的是找到的第一个的位置,没找到返回-1。从0开始
System.out.println("r4 : " + str1.indexOf("o"));
//查找字符串最后一次出现的位置lastIndexOf
System.out.println("r5 : " + str1.lastIndexOf("o"));
//删除字符串中的一个字符,字符串从0开始的 substring(a, b)返回指定起始位置(含)到结束位置(不含)之间的字符串
System.out.println("r6 : " + str1.substring(0, 5) + str1.substring(6));
//字符串替换,替换所有
System.out.println("r7 : " + str1.replace("o", "h"));
//字符串替换,替换所有
System.out.println("r8 : " + str1.replaceAll("o", "h"));
//字符串替换,替换第一个
System.out.println("r9 : " + str1.replaceFirst("o", "h"));
//字符串反转
System.out.println("r10 : " + new StringBuffer(str1).reverse());
//字符串分割
String [] temp = str1.split("\\ ");
for (String str : temp){
System.out.println("r11 : " + str);
}
//字符串转大写
System.out.println("r12 : " + str1.toUpperCase());
//字符串转小写
System.out.println("r13 : " + str1.toLowerCase());
//去掉首尾空格
System.out.println("r14 : " + str4.trim());
//是否包含,大小写区分
System.out.println("r15 : " + str1.contains("World"));
//返回指定位置字符
System.out.println("r16 : " + str1.charAt(4));
}
- 运行结果如下