Pull to refresh

Comments 70

Хотелось бы видеть вариант «от мала до велика: сервлеты, мидлеты и 2 слова о портлетах»: так курс будет иметь более практическую направленность, а работу с базовыми типами можно рассмотреть по ходу дела.
Спасибо за труд!
Боюсь, ближе к ночи напишу сначала про базовые типы — а то читатели курса будут на собственном опыте колоться об ==.
Вы активно взялись за дело — это не может не радовать!
а может слишком активно? Два урока за одни сутки. Или это потому что выходные? Просто в будние дни изучать материал в таком объеме не представляется возможным. Хотя всегда можно добавить в избранное и почитать потом. Но для меня такое стремительное изучение не подходит :)
Ну, на мой вгляд, не слишком. Главное, чтобы было, что изучать ;) Так что, если статьи полежат некоторое время непрочитанными — это не страшно, главное их наличие.
Единственное плохо, что потом такого активного обсуждения не будет :)
Если вы хотите осветить все из того что написали, то логично наверное начать с ООП, потом типы, потом swing, потом сервлеты, а так лично для меня интересны сервлеты, но со всем остальным я просто уже разобрался.
Вот по пакетам сразу вопрос. Столкнулся я с проблемой.
У меня в path в винде написано так: .;C:\Program Files\Java\jre1.6.0_07\lib\ext\QTJava.zip;D:\Dev\Java\3rdPartyComponents\
Последнее — это куда я кладу всякие библиотеки, которые мне нужны.
Запускаю NetBeans, в проекте подключаю к либам org.apache.commons.httpclient (commons-httpclient-3.1.jar лежит как раз в той папке).
Пишу import org.apache.commons.httpclient;

NetBeans ругается, говорит package org.apache.commons does not exist. Хотя когда я делал импорт там во всплывающем списке был этот пакет.

Как быть?

P.S.: пакет качал с оф.сайта.
в Path в винде написано? а с чего это NetBeans должен лезть именно в Path, чтобы найти библиотеки?
допишите lib в classpath вашего проекта в NetBeans-е
> а с чего это NetBeans должен лезть именно в Path, чтобы найти библиотеки?
Ну вероятно с того, что компилятор ява вроде как должен так делать.
> допишите lib в classpath вашего проекта в NetBeans-е
Добавил в свойствах проекта эту папку где только можно — не помогло.
Попутно обнаружил, что яве не нравится сам апачевский пакет. Залез в один из классов, обнаружил, что на объявление package org.apache.commons.httpclient; НетБинс тоже ругается: Incorrect Package

Я вообще в непонятках…
Ну вероятно с того, что компилятор ява вроде как должен так делать.
нет, для загрузки своих классов java использует classpath, не path, сосбсно об этом говорилось в начале статьи.

какие библиотеки вы используете еще в проекте? возможно нетбинс уже добавил какой-то httpclient (достаточно стандартный класс для jee приложений) и они просто конфликтуют…
Ну естесственно я имел в виду, что в виндовых переменных среды дописал к classpath'у свой путь. А path сказал потому, что он там же прописан, где и classpath.

Расскажу более подробно:
Сделал я пустой проект, подключил к нему библиотеку yarfraw (добавил в либы проекта yarfraw-0.92.jar и написал import yarfraw.io.FeedReader;).

Потом мне понадобилось скормить конструктору FeedReader объект типа HttpURL, который, как я понял, надо взять из пакета org.apache.commons.httpclient.
В архиве с yarfraw был commons-httpclient-3.1-beta1.jar, я подключил его точно так же, но import org.apache.commons.httpclient; не работал, как я уже говорил. Я подумал на бету, и скачал релиз той же версии commons-httpclient-3.1.jar. Убрал подключение беты, подключил это — такой же результат.

Вот собственно потому и пишу.
Подозреваю, что дело все же с правильностью подключения библиотеки…
— Если бы проблема была с бетой, версией java или версией библиотеки, вы бы скорее всего увидели что-то вроде BadClassVersion, NoSuchMethodException или еще чего в этом духе, но раз его просто ipmort не видет…
— попробуйте создать чистый проект только с commons-httpclient-3.1.jar и проверьте там import org.apache.commons.httpclient (да и уберите его из системного classpath-а, чтобы не было проблем в других проектах с другими версиями библиотеки)
— проверьте так же библиотеки, которые мог добавить NetBeans по-дефолту, возможно он добавляет какие-то свои стандартные javaee либы, которые уже содержать тот самый org.apache.commons.httpclient
Мне кажется последний вариант маловероятнен — ну не должен нетбинс по умолчанию включать апачевские библиотеки. Думаю, они на такое бы не пошли.
Всё, получилось.

Надо было:
1. Оставить в classpath только одну версию библиотеки.
2. Импортировать не org.apache.commons.httpclient, а org.apache.commons.httpclient.*. Почему нельзя было просто httpclient, я не понял. Может поясните?
Это вам я поясню. Импорт — это импорт класса, вы должны указывать его имя. Конструкция import пакет; не работает ровно потому, что она и не должна. Конструкция import пакет.*; работает потому что она указывает на набор классов (типа: все которые в этом пакете) а не на сам пакет. Так было задумано разработчиками.
А если в пакете нет классов, а есть только подпакеты, прокатит ли импорт пакет.*;, или надо будет обязательно делать
импорт пакет.подпакет1.*;
импорт пакет.подпакет2.*;

?
вообще-то выкиньте глобальную системную переменную classpath вообще. она имела смысл разве что в яве 1.1.х

основной явовский рантайм всегда находится сам по себе, если нормально установлена ява.
ваши собственные библиотеки надо прописывать в свойствах проекта в NetBeans, а при запуске из командной строки прописывать в параметрах к java
устраивать свалку из библиотек включаемую в classpath всех приложений вам может неоднократно повернуться боком
> устраивать свалку из библиотек включаемую в classpath всех приложений
> вам может неоднократно повернуться боком
А чем, если не секрет?
во-первых, часто нужно иметь специфическую версию библиотеки (и тут вы можете получить перекрытие совпадающих классов из библиотек разных версий)
во-вторых, библиотеки часто зависят друг от друга, что, в случае такой свалки, чревато проблемами из-за класслоадеров. подробное объяснение займет много времени, так что поверьте на слово или изучите концепцию дерева класслоадеров самостоятельно :)

кстати, если уж так хочется держать какие-то библиотеки в одном каталоге, который будет автоматом включаться в Classpath всех приложений, то для этого есть каталог jre\lib\ext\
но делать это не рекомендуется по вышеуказанным причинам :)
lib — в смысле commons-httpclient-3.1.jar
Там я уже включил это файл, я писал об этом в первом посте.
Попробуйте дописать ключ на вызов JVM: -cp путь_к_jar
> java -classpath C:/path/to/commons-httpclient-3.1.jar;D:/path/to/other.jar mypackage.MyAppMain
или
> java -jar E:/path/to/MyApp.jar
Вам правильно ниже написали, classpath != виндовый path
Чтобы добавить его вы дописываете ключ при вызове java: -classpath /путь/до/папки_или_джара
Вопрос автору: а как давно Вы знакомы с Java?
Примерно два года. Пишу на ней на работе — полтора. А что?
Стало интересно, сколько нужно времени, что бы приобрести хороший опыт программирования на Java :)
Зависит от того с чего начинать. На мой взгляд, не стоит сразу пытаться охватить все уровни познания, но при этом стоит знать всё и понемногу. Например после этого поста понятно как работает ClassLoader. А потом я могу рассказать, например, что можно создать свой, который будет классы, допустим, из сети вытягивать, и отдавать системному. Это будет интересно, но не нужно почти никому.
Так вот, подобного в Java навалом. Моё дело — рассказать о главном, а уж получать конкретный опыт — это нужно сидеть, и думать, что да как и разбираться. Ну и писать действительно работающие приложения…
Именно поэтому нельзя написать так:
import ru.vp.SuperClass;
import ru.mashka.SuperClass;

Ну не сказать уж что совсем нельзя, этим как раз активно пользуются обфускаторы P

Ну и про общие конструкторы рассказывать без объяснения обычных конструкторв конечно как-то странно, а вообще неплохой ликбес)
Странно, у меня не получается сделать такой импорт. пишет
имякласса is already defined in a single-type import

Про конструкторы расскажу, сейчас цель была дать понять что можно творить и чего стоит опасаться.
Неплохо бы было дополнить эту статейку табличкой уровня доступа к элементам класса пакета итд
Взято из книги Г.Шилдта
Всё это будет в следующей статье.
В примере с фреймом заголовок констрактора потерялся перед открытием фигурной скобки.
Хмм, не знал о такой фиче…
это с какой джавы есть такое?
В 1.4 уже было, если я правильно помню.
Блок вызывается при вызове любого из констракторов и исполняется перед основным кодом…
Да. Это, как написано, иногда называют обобщённым конструктором. Обычно толку от него ноль, так как вся инициализация зависит от параметров. А так — да, он перед каждым конструктором вызывается.
Ага, при необходимости вынести общий код есть более прозрачные методы, век живи, век учись :)
наверное, было бы лучшим тогда оставить и сам конструктор и фигурные скобки для наглядности
> зазипованная директория с сорцами с разрешением .jar
наверное, всё-таки «зазипованая директория с .class файлами и расширением .jar»?

Про загрузку классов тема не раскрыта, напишите например, как происходит загрузка класса HelloWorld
Что писать далее: расскажите про класс Class, reflection, почему может быть, что HelloWorld.class != HelloWorld.class (разные classloader-ы :) ) Static секции, модификаторы, анонимные классы.
Да, спасибо, стормозил.

Про загрузку классов можно рассказывать бесконечно, но мне кажется эта тема раскрыта настолько, насколько нужно.
Согласитесь, не каждый же день вы байт-код класса получаете по сокету и скармливаете лоадеру :)
Про структуру языка будет обязательно. Заодно про то, чем становятся enum'ы…
Хотелось бы видеть маны по созданию именно веб-приложений. Т.е. коннект к базе данных, работа с шаблонами и пр. Но до этого еще, наверное, далеко… (:
Лично меня больше интересуют Servlet + JSP, но это чисто с профессиональной точки зрения. Возможно другим читателям нужны именно мидлеты…

Забегая вперед, мне хотелось бы задать вопрос, который мне давно интересен, но как-то не у кого было спросить. Может быть автор сразу и ответит…

Вопрос такой: с точки зрения best practices Java и паттерна MVC сервлет является контроллером, т.е. он должен приять реквест + подготовить данные для View. Вопрос, как передать подготовленные данные из сервлета в JSP? Есть ли какой-то класс/паттерн для этого? Может быть есть какие ссылки под рукой на тему MVC в веб-приложениях под Java?

Вопрос, конечно, очень преждевременный, но, как говорится, наболело :)
Хороший вопрос, но ответ прост.
Вы должна использовать фильтры. Фильтр должен получать нужные вам данные и класть их в аттрибуты запроса, через
request.setAttribute
а в JSP:
request.getAttribute…
а при чем тут фильтры???
А где вы ещё собрались делать setAttribute?
конечно в сервлете.

стандартная логика

doPost(reqest,response) {
myLogic(myModel);
request.setAttribute(«model»,myModel);
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher("/myapp/my.jsp");
dispatcher.forward(request, response);
}
Можно и так, особой разницы нет. Или я ошибаюсь?
ну, я вашего примера не видел, потому не берусь сказать чем это чревато.
более того, я 1й раз в жизни слышу про такое использование фильтров.
во-первых, для простой задачи по передаче модели между контроллером и View это лишняя сущность в приложении, во-вторых, это использование сущности не по назначению.
Если, допустим (хотя это и не реальная ситуация), нам нужно отображать в каждом JSP юзер-агент человека, логично будет вынести определение UA в фильтр, а не вызывать его из каждого сервлета напрямую, нет?
неудачный пример привели с юзерагентом. это не часть обычного MVC потока.
вообще, подобные параметры или кладут в сессию, или включают тем или иным образом в состав основной страницы (tiles framework, sitemesh, jsp include)

более-менее крупные приложение сейчас никто не пишет на голых сервлетах, обычно используют MVC-фреймфорк на основе шаблона FrontController (готовый или самописный), соответственно, общую функциональность можно добавлять в него (в FC)

фильтры используют обычно для аутентификации, логгирования/отладки, работы с кодировками, работы с DB-сессией и т.д. фактически, это всё аспекты несколько иного уровня.
Что ж, думаю вы правы. К сожалению, про фильтры я только читал спецификацию, т.к. обычно имею дело только с Echo-интерфейсом, который реализуется достаточно «втупую» одним сервлетом, а логика переносится чуть глубже.
стандартный и самый частоиспользуемый способ передачи параметров для JSP View это request.setAttribute(«model»,myModel)
есть и более красивые способы, но они обычно требуют определенных оберток или фреймворков.

одна из лучших книг по теме: www.manning.com/fields2/ её можно скачать много где…
UFO just landed and posted this here
так, а нет ли случайно желающих начать со мной писать про groovy/grails?
Я бы с удовольствием почитал про Groovy — пишите.
Насчет продолжений — думаю сколько людей, столько и мнений, но, имхо, правильнее сначала рассмотреть собственно язык, буковки-циферки, ветвления-циклы, потом ООП, ну а потом оконные приложения. Хотя можно и сразу к оконным, объясняя все по ходу дела.
Интересно было бы почитать про сервлеты, начиная с самого начала. От выбора сервера, ИДЕ и заканчивая каким-нибудь работающим простым примерчиком.
Н и список литературы, откуда можно уже черпать что необходимо.
Так сказать быстрый старт
Знакомлюсь с Java по этим статьям. Сделал пример с Applet'ом.

import java.applet.Applet;
import java.awt.Graphics;

public class HelloWorld extends Applet{

public void paint(Graphics g){
g.drawString(«Hello World»,15,15);
}

}

Скомпилировал
javac HelloWorld.java

Сделал HTML-файл:

<body>
<applet code=«HelloWorld.class» codebase=«file:///D:/project/java/» width=«150» height=«30»></applet>
</body>
</pre>

Открываю в броузере, вижу в логах:

load: HelloWorld.class is not public or has no public constructor.
java.lang.IllegalAccessException: Class sun.plugin2.applet.Plugin2Manager can not access a member of class HelloWorld with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception: java.lang.IllegalAccessException: Class sun.plugin2.applet.Plugin2Manager can not access a member of class HelloWorld with modifiers ""

Что где не так?
Странно, у меня аналогичный код запускается нормально. Какой jre и браузер?
Java SE Development Kit (JDK) 6 Update 11
Java(TM) 6 Update 11
Firefox 3
А если добавить в код класс пустой конструктор:
public HelloWorld(){}
?
А так всё замечательно. Спасибо.
Sign up to leave a comment.

Articles