web编程
❤1、web编程基础
1、启动项目时如何实现不在链接里输入项目名就能启动?
修改Tomcat配置文件 server.xml。找到自己的项目配置 :
<Context docBase="oneProject" path="/one Project" reloadable="true"
source="org.eclipse.jst.jee.server:userManager"/>
改为如下配置:
<Context docBase="oneProject" path="/" reloadable="true"
source="org.eclipse.jst.jee.server:userManager"/>
经过这样的修改,项目就可以在启动服务器后不用输入项目访问了。
2、1分钟之内只能处理1000个请求,你怎么实现,手撕代码?
我知道的有两种方式可以实现:
a). Application 对所有用户访问的次数计数。同时定义一个计时器,单位为一分钟。如果Application 中的用户在单位时间内超出请求次数,就拒绝处理该请求。一分钟再刷新application的值为0.
使用一个Map 维护变量:
// 泛型 String 表示用户标识,List中存放用户不同请求的时间戳。
private Map<String, List> map = new ConcurrentHashMap<>();
我们只需要在单位计数中判断 List中数量是否超出限制即可。
b). 使用 aop 实现请求的限制,在需要限制的请求方法上加上 aop 逻辑。即可实现,思路如下:
自定义注解类实现请求限制的拦截逻辑,在需要限制的方法上使用注解,超出限制后拒绝处理请求。
3、什么时候用assert
在开发和测试过程中,很多时候我们需要对某些场景进行判断,当这个判断满足我们预期的答案,才继续往下执行,否则提出程序或者发出警告。assert就是这样的功能,满足判断时返回true,否则返回false。但是真正到系统上线的时候,这些assert是不要使用的。
5、JSP的内置对象及方法。
. 说一说四种会话跟踪技术。
a).表单隐藏域
在表单的提交中,加入这样一段数据提交的隐藏域,用户在输入时是看不到的,但是可以通过查看网页源代码来看到,在服务端只能通过post的方式获取参数。这种方式在禁用Cookie的情况下也能工作,但是关闭浏览器后就会失效。
b).URL重写
http://www.XXX.com/news?id=xxxx
在提交请求的URL后面加上请求需要的参数,常见的GET的请求。安全性能不高,参数可以在地址栏中看到,而且对于参数的长度有限制(1024字节),禁用Cookie的情况下也能使用,但是关闭浏览器后就会失效。
c).Cookie
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
// 新建一个Cookie
Cookie cookie = new Cookie("name", "pwd");
// 设置Cookie的生命周期
cookie.setMaxAge(Integer.MAX_VALUE);
// 将Cookie发送到客户端
resp.addCookie(cookie);
// Cookie的修改,创建一个和已有的cookie同名,然后再添加到客户端,自动修改
Cookie secCookie = new Cookie("name", "newPwd");
resp.addCookie(secCookie); // cookie修改
// cookie的删除, 创建一个和已有的cookie同名,并设置maxAge为0,添加到客户端,就会自动删除
Cookie thirCookie = new Cookie("name", "thirPwd");
thirCookie.setMaxAge(0); // 修改生命周期为0
resp.addCookie(thirCookie); // 删除客户端cookie
}
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,
就使用response向客户端浏览器颁发一个Cookie。 客户端浏览器会把Cookie保存起来,
并由浏览器通过域名管理不同网站的Cookie。
除了以上的Cookie属性之外,还写一些常用的属性,可以根据实际的需求设置。
d).Session
Session代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续的。在Servlet中,session指的是HttpSession类的对象。
Session创建时间的误解:一般的误解是Session在客户端访问的时候就会被创建,但其实 Session 的真正创建时机是服务端程序调用 HttpServletRequest.getSession(true) . 我们知道JSP中有个内置对象是session,其实那是因为在我们编写的JSP代码中,默认有这么一句:HttpSession session = HttpServletRequest.getSession(true);在将JSP编译为Servlet代码的时候,Session就会被创建。但是Session会占用服务器的内存,因此我们不需要的时候,最好将该属性置false。 <% @page session=”false”%>。
但客户端访问.html 等静态资源时,不涉及将JSP编译为Servlet,因此Session不会创建。当客户端第一次访问JSP页面时,服务器端将创建一个Session并保存在内存中,同时为客户端返回一个sessionID,以供客户端下次请求应用的时候带着sessionID来表明自己的身份。一次会话一个Session,Session通过sessionID来唯一标识。同时Session默认是在服务器的内存中维护的(虽然我们可以通过技术将session持久化),因此Session的长度不宜太大(虽然本身没有长度限制)。
Session原理:因为http是无状态的连接,Session也不能根据连接来识别是否是同一次会话,因此客户端第一次请求JSP/Servlet之后,服务端会自动生成一个名叫JSESSIONID的Cookie,该Cookie的值就是sessionID,发送到客户端,客户端再次连接的时候,会自动带上这个JSESSIONID,找到相应的session。如果客户端端禁用了Cookie,那么这个JSESSIONID会通过URL重写发送到服务端。
Session的生命周期:
它的生命周期不累加的,而Cookie的生命周期是累加的,不累加的意思就是Session的计时是从最近一次访问开始的,而Cookie是从开始到结束,无论你期间是否使用。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throw
s ServletException,
IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
// 真正的创建一个Session
HttpSession session = req.getSession(true);
// 设置Session的生命周期
session.setMaxInactiveInterval(Integer.MAX_VALUE);
}
6. 讲讲Request对象的主要方法
序号 方法简述
1 Cookie[] getCookies()
返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。
2 HttpSession getSession(boolean create)
返回与该请求关联的当前 HttpSession,或者如果没有当前会话,且创建是真的,则返回一个新的 session 会话。
3 Enumeration getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
4 Object getAttribute(String name)
以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。
5 String getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
6 String getMethod()
返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
7 String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。
8 String getRemoteHost()
返回发送请求的客户端的完全限定名称
9 String getRemoteAddr()
返回发送请求的客户端的互联网协议(IP)地址
10 String getRemoteHost()
返回发送请求的客户端的完全限定名称。
7.过滤器有哪些作用和用法?
过滤器的常见用途:
a).对用户的请求进行统一的认证、对访问的请求进行记录和审核
b).对用户传输的数据过滤和替换,转换图像格式,对响应内容进行压缩,减少网络传输
c).对用户的请求和响应进行加密处理
d).触发资源访问事件
Filter工作流程:
和 Filter相关的接口定义:
// 编写一个Filter需要 实现这个接口
public interface Filter {
// 初始化Filter
public default void init(FilterConfig filterConfig) throws ServletException {}
// Filter的逻辑实现,如果有多个Filter,必须在末尾执行 chain.doFilter(req, resp);
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
// 过滤器的销毁过程,可用于关闭该过滤器中打开的资源
public default void destroy() {}
}
// 当有多个过滤器连成一串的时候,知道真正的请求资源之前的一系列过滤
public interface FilterChain {
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException;
}
// 过滤器的配置相关
// 做Filter初始化的时候,作为参数传入,初始化关于过滤器的配置
public interface FilterConfig {
public String getFilterName();
public ServletContext getServletContext();
public String getInitParameter(String name);
public Enumeration<String> getInitParameterNames();
}
注意事项: Filter 的执行顺序是在 web.xml 中定义的顺序,在多个Filter中的chain 中,一定在处理完当前Filter的逻辑之后,调用chain.doFilter(request, response) 转到下一个Filter
简单例子:
/**
* 实现字符编码过滤的过滤器
* @author ytuan
*
*/
public class FilterTest implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
chain.doFilter(req, resp);
}
}
8.请谈谈你对Javaweb开发中的监听器的理解?
监听器示意图:
JavaWeb中的监听器按照事件源分为三大类:作用范围由大而小
a).ServletContext (针对整个应用程序上下文)
b).HttpSession (针对单个用户会话)
c).ServletRequest (针对某一次ServletRequest )
针对这以上这三种不同作用域的对象,又把对象本身的事件类型分为三种:
a).域对象自身的创建和销毁事件监听
b).域对象中属性的增删事件监听
c).监听绑定到HttpSession域中某个对象的状态事件监听
这里的对象创建和销毁包括三个,域对象中属性的增删包括ServletContext 和 ServletRequest 两个对象。需要重点注意一下HttpSession绑定的对象,它不同于前两者。
保存在Session域中的对象可以有多种状态:绑定(session.setAttribute(“bean”,Object))到Session中;从 Session域中解除绑定(session.removeAttribute(“bean”));随Session对象持久化到一个存储设备中;随Session对象从一个存储设备中恢复
Servlet 规范中定义了两个特殊的监听器接口"HttpSessionBindingListener和HttpSessionActivationListener"来帮助JavaBean 对象了解自己在Session域中的这些状态: ,实现这两个接口的类不需要 web.xml 文件中进行注册。
a). HttpSessionBindingListener接口
实现了HttpSessionBindingListener接口的JavaBean对象可以感知自己被绑定到Session中和 Session中删除的事件
当对象被绑定到HttpSession对象中时,web服务器调用该对象的void valueBound(HttpSessionBindingEvent event)方法
当对象从HttpSession对象中解除绑定时,web服务器调用该对象的void valueUnbound(HttpSessionBindingEvent event)方法
b).HttpSessionActivationListener接口
实现了HttpSessionActivationListener接口的JavaBean对象可以感知自己被活化(反序列化)和钝化(序列化)的事件
当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被钝化(序列化)之前,web服务器调用该javabean对象的void sessionWillPassivate(HttpSessionEvent event) 方法。这样javabean对象就可以知道自己将要和HttpSession对象一起被序列化(钝化)到硬盘中.
当绑定到HttpSession对象中的javabean对象将要随HttpSession对象被活化(反序列化)之后,web服务器调用该javabean对象的void sessionDidActive(HttpSessionEvent event)方法。这样javabean对象就可以知道自己将要和 HttpSession对象一起被反序列化(活化)回到内存中 (此处参考:https://www.cnblogs.com/xdp-gacl/p/3969249.html)
9.说说web.xml文件中可以配置哪些内容?
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!-- 配置web引用程序中Servlet上下文的初始化参数 -->
<context-param>
<param-name>name</param-name>
<param-value>ytuan996</param-value>
</context-param>
<!-- 当程序中发生错误时,跳转到哪一个页面。这里的错误可以是异常,也可以是错误码,但是只能是其中之一 -->
<error-page>
<exception-type></exception-type>
<error-code>500</error-code>
<location>error.jsp</location>
</error-page>
<!-- 配置自己定义的过滤器 -->
<filter>
<!-- 还可以在这里定义过滤器的自定义参数 -->
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>
<filter-name></filter-name>
<filter-class></filter-class>
</filter>
<!-- 过滤器的规则 -->
<filter-mapping>
<filter-name></filter-name>
<url-pattern></url-pattern>
</filter-mapping>
<!-- 监听器 -->
<listener>
<listener-class></listener-class>
</listener>
<!-- 配置Servlet -->
<servlet>
<servlet-name></servlet-name>
<servlet-class></servlet-class>
</servlet>
<!-- 配置Servlet的请求路径 -->
<servlet-mapping>
<servlet-name></servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
<!-- 配置访问应用的欢迎页面,一般是首页面 -->
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
</web-app>
10、说说weblogic中一个Domain的缺省目录结构?比如要将一个简单的helloWorld.jsp放入何目录下,然后在浏览器上就可打入主机?
Domain目录服务器目录applications,将应用目录放在此目录下将可以作为应用访问,
如果是Web应用,应用目录需要满足Web应用目录要求,jsp文件可以直接放在应用目录
中,Javabean需要放在应用目录的WEB-INF目录的classes目录中,设置服务器的缺省应
用将可以实现在浏览器上无需输入应用名。
❤2、web编程进阶
1、forward与redirect区别,说一下你知道的状态码,redirect的状态码是多少?
- 1.forward
request.getRequestDispatcher(“new.jsp”).forward(request, response); //转发到new.jsp
2.redirect
response.sendRedirect(“new.jsp”); //重定向到new.jsp
很明显一个是用request对象调用,一个是用response对象调用,那么,这两者有什么区别呢? - 一、数据共享方面 forward:转发页面和转发到的页面可以 共享request里面的数据 redirect:不能共享数据
- 二、地址栏显示方面
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL. - 三、本质区别 转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:
转发过程:客户浏览器发送http请求—>web服务器接受此请求—>调用内部的一个方法在容器内部完成请求处理和转发动作—>将目标资源
发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客
户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
重定向过程:客户浏览器发送http请求—>web服务器接受后发送302状态码响应及对应新的location给客户浏览器—>客户浏览器发现
是302响应,则自动再发送一个新的http请求,请求url是新的location地址—>服务器根据此请求寻找资源并发送给客户。在这里
location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的
路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。
重定向,其实是两次request:第一次,客户端request
A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。
2、servlet生命周期,是否单例,为什么是单例。
https://blog.csdn.net/xiaojiahao_kevin/article/details/51781946
4、Servlet执行时一般实现哪几个方法?
public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletRequest request,ServletResponse response)
public void destroy()
nit ()方法在servlet的生命周期中仅执行一次,在servlet引擎创建servlet对象后执行。Servlet在调用init方法时,会传递一个包含servlet的配置和运行环境信息的ServletConfig对象。如果初始化代码中要使用到ServletConfig对象,则初始化代码就只能在Servlet的init方法中编写,而不能在构造方法中编写。缺省的init()方法通常是符合要求的,不过也可以根据需要进行 override,比如管理服务器端资源,初始化数据库连接等,缺省的inti()方法设置了servlet的初始化参数,并用它 的ServeltConfig对象参数来启动配置,所以覆盖init()方法时,应调用super.init()以确保仍然执行这些任务。
service ()方法是servlet的核心,用于响应对Servlet的访问请求。对于HttpServlet,每当客户请求一个 HttpServlet对象,该对象的service()方法就要被调用,HttpServlet缺省的service()方法的服务功能就是调用与 HTTP请求的方法相应的do功能,doPost()和doGet(),所以对于HttpServlet,一般都是重写doPost()和doGet() 方法。
destroy()方法在servlet的生命周期中也仅执行一次,即在服务器停止卸载servlet之前被调用,把servlet作为 服务器进程的一部分关闭。缺省的destroy()方法通常是符合要求的,但也可以override,来完成与init方法相反的功能。比如在卸载servlet时将统计数字保存在文件 中,或是关闭数据库连接或IO流。
getServletConfig()方法返回一个servletConfig对象,该对象用来返回初始化参数和servletContext。servletContext接口提供有关servlet的环境信息。
getServletInfo()方法提供有关servlet的描述信息,如作者,版本,版权。可以对它进行覆盖。
6、说说Servlet接口中有哪些方法?
7、Servlet 3中的异步处理指的是什么?
3以前处理业务处于阻塞状态,三以后业务异步执行,servlrt直接返回处理其他请求,等待业务直接响应
8、如何在基于Java的Web项目中实现文件上传和下载?
10、Servlet中如何获取用户提交的查询参数或表单数据?
username=request.getParameter(“username”)
11、Servlet中如何获取用户配置的初始化参数以及服务器上下文参数?
12.取得上下文初始化参数?**
1.servlet的ServletConfig对象拥有该servlet的ServletContext的一个引用,所以可这样取得上下文初始化参数:
getServletConfig().getServletContext().getInitParameter()
2.也可以在Servlet中直接调用getServletContext().getInitParameter()
13、说说MVC的各个部分都有那些技术来实现?如何实现?
- model:应用的业务逻辑(如:数据库的操作),通过JavaBean实现 (hibernate、mybatis、ibatis)
- view:视图层,用于与用户的交互,主要由jsp页面产生。
(jsp、FreeMarker、tails、taglib、EL、Velocity ) - controller:处理过程控制,一般是一个servlet。 它可以分派用户的请求并选择恰当的视图以用于显示
同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。 (severlet、struts、spring、action)
14、什么是DAO模式?
DAO(Data Access Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露底层持久化方案实现细节的前提下提供了各种数据访问操作。
在实际的开发中,应该将所有对数据源的访问操作进行抽象化后封装在一个公共API中。
用程序设计语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口,在逻辑上该类对应一个特定的数据存储。
DAO模式实际上包含了两个模式,一是Data Accessor(数据访问器),二是Data Object(数据对象),前者要解决如何访问数据的问题,而后者要解决的是如何用对象封装数据。
15、请问Java Web开发的Model 1和Model 2分别指的是什么?
Model1:
Model1的中心是JSP页面,JSP页面中结合业务逻辑、服务端处理过程和HTML等,这样就在JSP页面中同时实现了业务逻辑和流程控制。从而快速开发。
Model1的优缺点:
优点:简单,快速开发,适用小规模开发;
缺点:业务逻辑和表示逻辑混合在JSP页面中没有进行抽象和分离,JSP负载太大。所以非常不利于应用系统业务的重用和改动,不便于维护。
Model2:
Model 2表示的是基于MVC模式的框架。MVC “Model”代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),“View”是应用的表示面(由JSP页面产生), “Controller ”是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。从而弥补了Model1的不足。
Model2其实是在Model1基础上又抽了一层控制层。
最经典的Model2:jsp + javabean + servlet
Model2缺点:
优点:具有组件化的优点从而更易于实现对大规模系统的开发和管理。职责划分清晰。
缺点:不适合小项目开发。
❤3、web编程原理
1、get和post区别?
见笔记
4、cookie 和session 的区别?
见笔记
7、如何设置请求的编码以及响应内容的类型?
通过请求对象(ServletRequest)的setCharacterEncoding(String)方法可以设置请求的编码,其实要彻底解决乱码问题就应该让页面、服务器、请求和响应、Java程序都使用统一的编码,最好的选择当然是UTF-8;通过响应对象(ServletResponse)的setContentType(String)方法可以设置响应内容的类型,当然也可以通过HttpServletResponsed对象的setHeader(String, String)方法来设置。
10、大型网站在架构上应当考虑哪些问题?
1、分层:
分层是处理任何复杂系统最常见的手段之一,将系统横向切分成若干个层面,每个层面只承担单一的职责,通过下层为上层提供的支撑和服务以及上层对下层的调用来形成一个完整的复杂的系统。
比较常见的分层模式是MVC,将软件系统分为持久层(提供数据存储和访问服务)、业务层(处理业务逻辑,系统中最核心的部分)和表示层(系统交互、视图展示)。
需要指出的是:
分层是逻辑上的划分,在物理上可以位于同一设备上也可以在不同的设备上部署不同的功能模块,这样可以使用更多的计算资源来应对用户的并发访问;
层与层之间应当有清晰的边界,这样分层才有意义,才更利于软件的开发和维护。
2、分割
分割是对软件的纵向切分。我们可以将系统的不同功能和服务分割开,形成高内聚低耦合的功能模块(单元)。在设计初期可以做一个粗粒度的分割,将系统分割为若干个功能模块,后期还可以进一步对每个模块进行细粒度的分割,这样一方面有助于软件的开发和维护,另一方面有助于分布式的部署,提供网站的并发处理能力和功能的扩展。
3、分布式
除了上面提到的内容,网站的静态资源(JavaScript、CSS、图片等)也可以采用独立分布式部署并采用独立的域名,这样可以减轻应用服务器的负载压力,也使得浏览器对资源的加载更快。数据的存取也应该是分布式的,传统的商业级关系型数据库产品基本上都支持分布式部署,而新生的NoSQL产品几乎都是分布式的。当然,网站后台的业务处理也要使用分布式技术,例如查询索引的构建、数据分析等,这些业务计算规模庞大,可以使用Hadoop以及MapReduce分布式计算框架来处理。
4、集群
集群使得有更多的服务器提供相同的服务,可以更好的提供对并发的支持
5、缓存
所谓缓存就是用空间换取时间的技术,将数据尽可能放在距离计算最近的位置。使用缓存是服务器优化的第一定律。我们通常说的CDN、反向代理、热点数据都是对缓存技术的使用。
6、异步
异步是实现软件实体之间解耦合的又一重要手段。异步架构是典型的生产者消费者模式,二者之间没有直接的调用关系,只要保持数据结构不变,彼此功能实现可以随意变化而不互相影响,这对系统的扩展非常有利。使用异步处理还可以提高系统可用性,加快服务器的响应速度,同时还可以起到削峰作用,应对瞬时高并)。
能推迟处理的都要推迟处理是服务器优化的第二定律,而异步是践行服务器优化第二定律的重要手段。
7、容灾
各种服务器都要提供相应的容灾服务器以便在某台或某些服务器宕机时还能保证网站可以正常工作,同时也提供了灾难恢复的可能性。冗余是系统高可用性的重要保证。
11、请对J2EE中常用的名词进行解释(或简单描述
web容器
JTA:(Java Transaction API)JAVA事务服务。提供各种分布式事务服务。应用程序只需调用其提供的接口即可。
JAF:(Java Action FrameWork)JAVA安全认证框架。提供一些安全控制方面的框架。让开发者通过各种部署和自定义实现自己的个性安全控制策略。