Главная » Java, Web » Заголовки HTTP в ответе сервера

0

Как правило, ответ сервера включает в себя несколько заголовков, в том числе статус-код. С некоторыми статус-кодами предполагается использование определенного набора заголовков. Итак, статус-код 401 (Unauthorized) предполагает наличие заголовка www-Authenticate. Наиболее удобный способ генерирования заголовков — использование метода setHeader (интерфейс HttpServletResponse). В качестве параметров метод получает имя заголовка и значение для этого типа заголовка. Существует два специальных метода для работы с заголовками — это метод для работы с датами setDateHeader и метод для работы с целыми значениями setlntHeader. Первый метод переводит дату в миллисекунды, в том формате, который возвращается методом System. currentTimeMillis ИЛИ методом getTime В применении к объекту типа Date. Второй метод помогает производить преобразование целого значения в строку.

Интерфейс HttpServletResponse содержит набор методов, облегчающих работу с общепринятыми заголовками. Метод setcontentType задает заголовок content-Type. Метод применяется в большинстве сервлетов. Метод

setcontentLength задает заголовок content-Length. Этот заголовок полезен в том случае, если браузер поддерживает персистентные соединения. Метод addCookie задает Cookies. Метод sendRedirect задает заголовок Location.

Общепринятые заголовки и их назначение

Ниже приводится список наиболее употребительных и общепринятых HTTP-заголовков, используемых при генерации ответа сервером.

?    Allow

Методы запроса, поддерживаемые сервером (например, get, post и т. п.).

?    Content-Encoding

Метод кодирования документа.

?    Content-Length

Количество байтов, посылаемых в ответе. Используется при персистент- ных соединениях.

?    Content-Type

Тип mime посылаемого документа.

?    Date

Текущее время и дата.

?    Expires

Срок годности посылаемого документа.

?    Last-Modified

Время последнего изменения посылаемого документа.

?    Location

Местоположение документа (при переадресации).

?    Refresh

Как часто браузер должен запрашивать измененную страницу, указывается интервал в секундах. (Например, setHeader ("Refresh", "5; URL=http://host/path"). Аналогичный результат может быть достигнут с использованием ярлыка <мета>: <мета http-equiv=" Re fresh" CONTENT="5; URL=http://host/path">.)

?    Server

Тип сервера.

?    Set-Cookie Задание Cookies.

?    WWW-Authenticate

Тип аутентификации, например response. setHeader ("WWW-Authenticate", "BASIC realm=\"executives\"").

Пример периодически загружаемой страницы, содержимое которой меняется со временем, приведен в листинге 4.13. Пользовательский интерфейс

выполнен в виде HTML-страницы. Это самообновляющаяся страница. Страница взаимодействует с сер влетом PrimeNumbers.class (листинг 4.14), вычисляющим простые числа.

Листинг 4.13. Файл PrlmeNumbers.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Finding Large Prime Numbers</ТITLE> </HEAD>

<BODY BGCOLOR="#FDF5E6">

<H2 ALIGN="CENTER">Поиск простых чисел</Н2>

<BRXBR>

<CENTER>

<FORM ACTION="http://localhost:81/PrimeNumbers"> <В>Сколько простых чисел найти:</B>

<INPUT TYPE="TEXT" NAME="numPrimes" VALUE=25 SIZE=4XBR> <В>Количество десятичных знаков в простом числе:</В> <INPUT TYPE="TEXT" NAME="numDigits" VALUE=150 SIZE=3XBR> <INPUT TYPE="SUBMIT" VALUE="Start Calculating"> </FORM> </CENTER> <BRXBR>

Этот пример призван продемонстрировать два свойства сервлетов Java- servlets:

<UL>

<Ъ1ХВ>Способность сервлетов поддерживать персистентную связь.</В> В этом случае сервлет выполняет низкоприоритетный поток, который вычисляет простые числа.

Когда клиент запрашивает обновление, сервлет посылает новые данные (если есть) .

Сервлет также поддерживает набор из 30 последних полученных результатов. Это на тот случай, если клиент запросит то, что уже ранее было вычислено.

<Ъ1><В>Способность сервлетов работать с заголовками НТТР.</В> В нашем случае сервлет посылает заголовок <CODE>Refresh</CODE> в том случае, если процесс вычисления все еще не завершен. После этого заголовка выводится страница, содержащая промежуточный результат.

</UL>

<HR>

</BODY>

</HTML>

Листинг 4,14, Файл PrlmeNumbers.java

package paket; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*;

Сервлет, создающий набор последовательных простых чисел общим

количеством п, каждое число содержит m знаков.

Вычисления производятся в отдельном низкоприоритетном потоке,

результат выводится с отображением только тех чисел,

которые уже вычислены.

Если процесс вычисления не закончен,

то апплет посылает браузеру заголовок Refresh

с указанием времени повторного обращения к серверу

для отображения ранее непросчитанных простых чисел.

Сервер также поддерживает список ранее вычисленных чисел,

которые могут быть возвращены клиенту

при его запросе немедленно без вычислений.

public class PrimeNumbers extends HttpServlet {

private static Vector primeListVector = new Vector(); private static int maxPrimeLists = 30; public void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException { int numPrimes =

ServletUtilities.getlntParameter(request, "numPrimes", 50); int numDigits =

ServletUtilities.getlntParameter(request, "numDigits", 120); PrimeList primeList =

?indPrimeList(primeListVector, numPrimes, numDigits); if (primeList = null) {

primeList = new PrimeList(numPrimes, numDigits, true); synchronized(primeListVector) {

if (primeListVector.size() >= maxPrimeLists)

primeListVector.removeElementAt(0); primeListVector.addElement(primeList);

}

}

Vector currentPrimes = primeList.getPrimes(); int numCurrentPrimes = currentPrimes.size(); int numPrimesRemaining = (numPrimes — numCur rent Primes) ; boolean isLastResult = (numPrimesRemaining == 0) ; if (!isLastResult) {

response.setHeader("Refresh", "5") ;

}

response.setContentType("text/html"); Printwriter out = response.getWriter();

String title = "Some " + numDigits + "-Digit Prime Numbers"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H2 ALIGN=CENTER>" + title + "</H2>\n" + "<H3>Primes found with " + numDigits + " or more digits: " + numCurrentPrimes + ".</H3>"); if (isLastResult)

out.printIn("<B>Done searching.</B>"); else

out.println("<B>Still looking for " + numPrimesRemaining + " more<BLINK>…</BLINK></B>"); out.println("<OL>") ;

for(int i=0; i<numCurrentPrimes; i++) {

out.printIn(" <LI>" + currentPrimes.elementAt(i));

}

out.println("</OL>") ;

out. println ("</BODYX/HTML>") ;

}

public void doPost(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException { doGet(request, response);

Проверка того, есть ли уже вычисленные ранее числа или происходит ли в данный момент вычисление чисел, совпадающих с условиями нового запроса.

Если числа такие есть, то повторные вычисления производиться не будут.

Поддерживаемый список не должен быть большим,

чтобы не занимать много памяти.

Доступ к списку должен быть синхронизирован

во избежание возникновения одновременных запросов.

private PrimeList findPrimeList(Vector primeListVector,

int numPrimes, int numDigits) { synchronized(primeListVector) {

for(int i=0; i<primeListVector.size(); i++) {

PrimeList primes = (PrimeList)primeListVector.elementAt(i); if ((numPrimes == primes.numPrimes()) && (numDigits == primes.numDigits())) return(primes);

}

return(null);

}

Помимо этого файла потребуются еще два файла PrimeList.java (листинг 4.15) и Primes.java (листинг 4.16).

Листинг 4.15. Файл PrimeList.java

package paket;

import java.util.*;

import java.math.Biglnteger;

создается вектор больших простых чисел

public class PrimeList implements Runnable { private Vector primes; private int numPrimes, numDigits;

// находим простые числа numPrimes; каждое число содержит количество // цифр, не меньшее, чем numDigits public PrimeList(int numPrimes, int numDigits, boolean runlnBackground) { // используем Vector, но не ArrayList // (для совместимости с JDK 1.1) primes = new Vector(numPrimes); this. numPrimes = numPrimes ; this.numDigits = numDigits; if (runlnBackground) {

Thread t = new Thread(this); // устанавливаем низкий приоритет, // чтобы не "затормозить" работу сервера t.setPriority(Thread.MIN_PRIORITY); t.start(); } else { run();

}

}

public void run() {

Biglnteger start = Primes.random(numDigits); for(int i=0; icnumPrimes; i++) { start = Primes.nextPrime(start); synchronized(this) {

primes.addElement(start) ;

}

}

}

public synchronized boolean isDone() { return(primes.size() == numPrimes);

}

public synchronized Vector getPrimes() { if (isDone()) return(primes);

else

return((Vector)primes.clone());

}

public int numDigitsO { return(numDigits);

}

public int numPrimesO { return (numPrimes) ;

}

public synchronized int numCalculatedPrimes() { return(primes.size());

}

j Листинг 4,16. Файл Prlmes.java

package paket;

import java.math.Biglnteger;

Утилиты, используемые для создания больших простых чисел.

Случайное большое целое число Biglnteger;

следующее простое число должно быть больше этого целого числа.

public class Primes {

private static final Biglnteger ZERO = new Biglnteger("0"); private static final Biglnteger ONE = new Biglnteger ("1"); private static final Biglnteger TWO = new Biglnteger("2"); private static final int ERR_VAL = 100; public static Biglnteger nextPrime(Biglnteger start) { if (isEven(start))

start = start.add(ONE); else

start = start.add(TWO); if (start.isProbablePrime(ERR_VAL))

return(start); else

return(nextPrime(start));

}

private static boolean isEven(Biglnteger n) { return(n.mod(TWO).equals(ZERO));

}

private static StringBuffer[] digits =

{ new StringBuffer("0"), new StringBuffer("1"), new StringBuffer("2"), new StringBuffer("3"), new StringBuffer("4"), new StringBuffer("5"), new StringBuffer("6"), new StringBuffer("7"), new StringBuffer("8"), new StringBuffer("9") };

private static StringBuffer randomDigit() {

int index = (int)Math.floor(Math.random() * 10); return(digits[index]);

}

public static Biglnteger random (int numDigits) { StringBuffer s = new StringBuffer(""); for(int i=0; icnumDigits; i++) { s.append(randomDigit() ) ;

}

return(new Biglnteger(s.toString()));

}

public static void main(String[] args) { int numDigits; if (args.length > 0)

numDigits = Integer.parselnt(args[0]); else

numDigits = 150; Biglnteger start = random(150); for(int i=0; i<50; i++) { start = nextPrime(start);

System.out.printIn("Prime "+!+"="+ start);

}

}

}

Основная HTML-страница показана на рис. 4.13. Промежуточные результаты показаны на рис. 4.14 и 4.15, а окончательный результат показан на рис. 4.16.

Рис. 4.13. Отображаемая HTML -страничка

 

Рис. 4.14. Некоторые числа уже вычислены и отображены в браузере

Рис. 4.15. Браузер получил дополнительные промежуточные результаты

 

Рис. 4.16. Сервлет завершил рассчет

Источник: Будилов В. А. Интернет-программирование на Java. — СПб.: БХВ-Петербург, 2003. — 704 е.: ил.

По теме:

  • Комментарии