更新时间: 试题数量: 购买人数: 提供作者:

有效期: 个月

章节介绍: 共有个章节

收藏
搜索
题库预览
(共35分)编写代码实现根据用户在浏览器URL中请求的资源返回对应的结果数据
HTTP请求的组成如下:
-------------------------------------------------------------------------------------
Public class HttpHomework {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final String CRLF = "\r\n";
try {
ServerSocket server = new ServerSocket(8080);
ScheduledThreadPoolExecutor executor = new _______【1】_______(30);
while (___【2】___) {
final Socket con = server.accept();
Runnable serverThread = new Runnable() {
public void __【3】____{
try {
HttPBufferedInputStream blis = new HttPBufferedInputStream(con.____【4】____);//按行读取数据的工具
byte[] buf = new byte[1024];
int c = blis.readLine(buf, 0, buf.___【5】__);
String res = new String(buf, 0, c);
String[] elements = res.split(" ");
res = elements[__【6】___].substring(___【7】___);
File f = new File(res);
FileInputStream fis = new FileInputStream(f);
long length =f.__【8】____;
OutputStream os = con._____【9】___;
String responseHeader = "HTTP/1.1 200 OK" + CRLF;
if (res.endsWith(".htm") || res.endsWith(".html")) {
responseHeader += "_______【10】________: text/html"
+ CRLF;
} else {
responseHeader += "_______【11】_____: application/stream"
+ CRLF;
}
responseHeader += "Content-Length: " + length
+ CRLF;
responseHeader += ___【12】________;
os.write(responseHeader.getBytes());
while ((c = fis.read(buf, 0, buf.length)) !=___【13】____) {
os.write(buf, 0, c);
}
fis.close();
os.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
executor.______【14】_________(serverThread);
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
辅助工具类(行优先读取Http输入流的工具,无需修改或填充空白 ):
-----------------------------------------------------------------
Import java.io.IOException;
Import java.io.InputStream;
/**
* 行优先读取Http输入流的工具
* @author
*/
Public class HttPBufferedInputStream {
InputStream is;
public HttPBufferedInputStream(InputStream is) {
this.is = is;
}
/**
* 以行优先方式读取流中数据,直到换行或缓冲区读满
*/
public int readLine(byte[]
B, int off, int len) throws IOException {
if (len<= 0) {
return 0;
}
int count = 0, c;
while ((c = is.read()) != -1) {
b[off++] = (byte) c;
count++;
if (c == '\n' || count == len) {
break;
}
}
return count > 0 ? count : -1;
}
}
【1】 ____________________
【2】____________________
【3】____________________
【4】____________________
【5】____________________
【6】____________________
【7】____________________
【8】____________________
【9】____________________
【10】____________________
【11】____________________
【12】____________________
【13】____________________
【14】____________________
信号量是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。
信号量工具类中需要提供一些必要的参数信息,包括:用于阻塞线程的资源锁列表、信号量许可的数量、当前还可用的许可数量、是否允许许可数量随环境变化而增长、信号量是否遵循公平原则(先阻塞等待的线程优先唤醒)、随机唤醒等待线程的随机工具等。请完成一个典型的信号量工具:
Public class Semaphore {
private List<Object> locks = Collections.synchronizedList(new ___ArrayList___<Object>());
private int permitNum = 1;
private int nowPermitNum = 1;
private boolean permitNumGrow = false;
private boolean fair = false;
Random random = new Random();
public Semaphore(int permitNum, boolean permitNumGrow, boolean fair) {
this.permitNum = permitNum;
this.nowPermitNum = permitNum;
this.permitNumGrow = permitNumGrow;
this.fair = fair;
}
public Semaphore(int permitNum) {
this(permitNum, true, false);
}
public Semaphore() {
this(1);
}
public void acquire() {
Object lock = new Object();
synchronized (____lock______) {
if (nowPermitNum > 0) {
nowPermitNUm--____;
} else {
locks.add(___lock___);
try {
____lock.wait()___________;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
public void release() {
if (locks.size() > 0) {
int index = 0;
if (!fair) {
index = Math.abs(random.nextInt()) % locks.size();
}
Object lock = locks.get(___index___);
locks.remove(__lock____);
synchronized (____lock_______) {
___lock.notity()_______;
}
} else if (nowPermitNum < __permitNum_____|| permitNumGrow) {
___nowPermitNum ++________;
}
}
public ___int___ getAvailablePermitNum() {
return nowPermitNum;
}
}
编写代码实现根据用户在浏览器URL中请求的资源返回对应的结果数据
HTTP请求的组成如下:
Public class HttpHomework {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final String CRLF = "\r\n";
try {
ServerSocket server = new ServerSocket(8080);
lExecutor executor = new ____ScheduledThreadPoolExecutor__________(30);
while (__true____) {
final Socket con = server.accept();
Runnable serverThread = new Runnable(){
public void __run()____{
try {
HttPBufferedInputStream blis = new HttPBufferedInputStream(con._getInputStream()_______);//按行读取数据的工具
byte[] buf = new byte[1024];
int c = blis.readLine(buf, 0, buf.length_____);
String res = new String(buf, 0, c);
String[] elements = res.split(" ");
res = elements[__1_].substring(___1___);
File f = new File(res);
FileInputStream fis = new FileInputStream(f);
long length =f._length()_____;
OutputStream os = con.getOutputStream ()________;
String responseHeader = "HTTP/1.1 200 OK" + CRLF;
if (res.endsWith(".htm") || res.endsWith(".html")) {
responseHeader += "____Content-Type________: text/html"
+ CRLF;
} else {
responseHeader += "____Content-Type____: application/stream"
+ CRLF;
}
responseHeader += "Content-Length: " + length
+ CRLF;
responseHeader += ___CRLF________;
os.write(responseHeader.getBytes());
while ((c = fis.read(buf, 0, buf.length)) !=___-1____) {
os.write(buf, 0, c);
}
fis.close();
os.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
executor.____execute___________(serverThread);
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
编写代码解决利用Servlet/JSP构建MVC应用后的重复提交问题(Servlet利用forward方式跳转JSP后出现的问题)
解决方案:提交数据表单前在请求和会话中生成相同的随机令牌字符串,在表单中添加一个隐藏域保存同样的随机令牌字符串,提交表单后,在Servlet中判定请求中的令牌字符串和会话中的令牌是否一致,如果一致则说明是第一次提交,则处理数据,并删除会话中的令牌字符串,重复刷新时由于会话中的字符串已经被删除,和请求中保存的令牌不一致,则略过数据处理流程。
在展现数据提交表单前,通过一个Servlet创建随机令牌字符串,然后跳转到表单页面:
Protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String token = UUID.randomUUID().toString();
request.getSession(true).setAttribute(REPEAT_SUBMIT_TOKEN_NAME,______);
request.setAttribute("token",______);
request.getRequestDispatcher("/jsppage/repeatsubmitdealing.jsp").forward(____________, ___________);
}
表单页面中需要使用一个隐藏域来随请求提交刚才生成的令牌字符串:
<form method="post" action="RepeatSubmitDealingStep2Quickstart">
账 号:<input type="text" name="username" /><br />
密码:<input type="password" name="password" /><br />
<input type="hidden" name="token" value="${__ _____}" />
<input type="submit" value="确定" />
</form>
最后在数据处理的Serlvet中验证令牌字符串是否一致来判定是不是出现了重复提交的问题:
String sessionToken = request.getSession(true)
.getAttribute(RepeatSubmitDealingStep1Quickstart.REPEAT_SUBMIT_TOKEN_NAME).toString();
String requestToken = request.getParameter("____");
If (requestToken.equals(____________)) {

}
以下代码是华为OBS服务的工具类,把代码补充完整
Ø 用于初始化OBS SDK客户端的参数信息对象
Public class OBSParameter {
/**
* 访问OBS桶的endPoint,可以在OBS的控制台中查看
*/
private String endPoint = "obs.cn-north-1.myhuaweicloud.com";
/**
* 访问OBS桶的用户ak
*/
private String ak = "TUTJ5WCO5NZRW9PIFVYT";
/**
* 访问OBS桶的用户sk
*/
private String sk = "R2xq1Ue96x1pYHY4pIyqH2NezT73spImVmMVeSMc";
public String getEndPoint() {
return endPoint;
}
public void setEndPoint(String endPoint) {
this.endPoint = endPoint;
}
public String getAk() {
return ak;
}
public void setAk(String ak) {
this.ak = ak;
}
public String getSk() {
return sk;
}
public void setSk(String sk) {
this.sk = sk;
}
}
Ø 用于使用OBS SDK操作对象文件的工具类
Public class OBSUtil {
/**
* 构建OBS SDK客户端需要依赖的核心参数
*/
OBSParameter parameter = new OBSParameter();
/**
* 获取对象列表的方法
*
* @param bucketName 桶的名称
* @return 该桶中的对象列表
*/
public ObjectListing getObjectList(String bucketName) {
// 利用系统提供的参数构建OBS SDK客户端
ObsClient obsClient = new ObsClient(parameter.getAk(), parameter.getSk(), parameter.getEndPoint());
// 列举对应桶中的对象
ObjectListing objectListing = obsClient.________ (bucketName);
try {
// 关闭客户端操作
obsClient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
..printStackTrace();
}
// 返回对象列表
return ________;
}
/**
* 获取对象名称列表的方法
*
* @param bucketName 桶的名称
* @return 该桶中的对象名称列表
*/
public List<String> getObjectKeyList(String bucketName) {
// 创建对象名称列表
ArrayList<String> keys = new ArrayList<String>();
// 获取桶中的对象列表
ObjectListing listing = _________(bucketName);
// 获取每个对象的名称并放在列表中
for (ObsObject obsObject : listing.getObjects()) {
____.add(obsObject._______);
}
return ______;
}
/**
* 以文件的方式上传对象的方法
*
* @param bucketName 桶的名称
* @param objectName 对象名称
* @param localFile 本地文件路径
*/
public void uploadToOBSBucketByFile(String bucketName, String objectName, String localFile) {
// 利用系统提供的参数构建OBS SDK客户端
ObsClient obsClient = new ObsClient(parameter.getAk(), parameter.getSk(), parameter.getEndPoint());
// 上传文件
obsClient.putObject(_____, _____, new File(______));
try {
// 关闭客户端操作
obsClient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
.e.printStackTrace();
}
}
}
1