• Можно ли добавить новый метод в класс во время исполнения?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Любые манипуляции (на уровне JVM) с классами в рантайме возможны при помощи библиотек, работающих с байткодом (тот же cglib или asm) и кастомным javaagent. Есть проекты вроде JRebel, DCEVM или Spring Loaded, которые позволяют менять логику в рантайме (опять же при помощи указанных уже инструментов).

    Использовать такие инструменты в продакшне противопоказано, а в разработке они бесполезны при TDD.

    UPD: ответ на вопрос: можно, но нужно ли?
    Ответ написан
    Комментировать
  • Как JPA находит все классы помеченный @Entity?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    При конфигурировании Hibernate/JPA указывается список @Entity-классов, либо базовый пакет, относительно которого производится поиск классов, помеченных аннотацией @Entity. Для этого есть метод SomeClass.class.isAnnotationPresent().

    PS: ИМХО, писать аналог JPA "в образовательных целях" - не лучшая идея.
    Ответ написан
    2 комментария
  • Как работать с enum в Java?

    eugene_leshchinskiy
    @eugene_leshchinskiy
    ошибка версии Java. использйте Java 5 или выше
    Ответ написан
    2 комментария
  • Почему не работает защита от межсайтового скриптинга в spring security?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Java
    Седой и строгий
    Всё правильно, вы в ajax-запросе не передаёте csrf-token, соответственно, он выглядит как злономеренный и не обрабатывается. Про это есть в документации.

    <html>
        <head>
            <meta name="_csrf" content="${_csrf.token}"/>
            <meta name="_csrf_header" content="${_csrf.headerName}"/>
            ...
        </head>
        ...
    </html>


    var csrfHeaderName = "X-CSRF-TOKEN";
    var csrfTokenValue;
    
    var metaTags = document.getElementsByTagName('meta'); 
    for(var i = 0; i < metaTags.length; i++) {
        var metaTagName = metaTags[i].getAttribute("name");
        if(metaTagName === "_csrf_header")
            csrfHeaderName = metaTags[i].getAttribute("content");
        if(metaTagName === "_csrf")
            csrfTokenValue = metaTags[i].getAttribute("content");
    }
    
    ...
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "userChangeTariff?tariffId=" + num1 + "&contractNumber=" + num2, false);
    xhr.setRequestHeader(csrfHeaderName, csrfTokenValue);
    xhr.send();
    Ответ написан
    1 комментарий
  • Почему контроллер не изменяет атрибутов?

    @void01
    он не должен ничего поменять на странице, он должен в ответе прислать тебе новое тело страницы с YES!
    посмотри респонс в нетворк таб дев тулза

    то, что ты видишь изначально - 1 страница
    то, что получаешь результатом аякс запроса - совсем другая, они никак не связаны.
    все что ты можешь сделать - это:
    1. отвечать например json-ом и по результатам аякса менять на странице содержимое определенных блоков...
    щас пример набросаю

    @RequestMapping(value = "/adminNewClient", method = RequestMethod.DELETE)
        public @ResponseBody Map adminNewClientPost(HttpServletResponse response, HttpServletRequest request,
                                         @RequestParam(value = "name") String name,
                                         @RequestParam(value = "surName") String secondName,
                                         @RequestParam(value = "birthday") String birthdayDate,
                                         @RequestParam(value = "passport") String passport,
                                         @RequestParam(value = "adress") String adress,
                                         @RequestParam(value = "email") String eMail,
                                         @RequestParam(value = "number") String number) {
         LinkedHashMap result = new LinkedHashMap();
         result.put("nameStat","YES!");
         return result;
      }

    в JSP
    <tr>
      <td><input id="surName" type="text" class="form-control" placeholder="Surname"></td>
       <td><span style="color:blue;" id="nameStat">${nameStat}</span></td>
     </tr>

    в JS
    function popBox() {
                                x = confirm('Are you sure? ');
                                if (x == true) {
                                    var xhr = new XMLHttpRequest();
    xhr.onload = function(){
    var jsonResponse = JSON.parse(this.responseText);
    for(var index in jsonResponse) { 
       if (jsonResponse.hasOwnProperty(index)) {
          document.getElementById(index).innerText = jsonResponse[index];
       }
    }
    };
                                    xhr.open("DELETE", "adminNewClient?name=" + name + "&surName=" + surName
                                            + "&birthday=" + birthday + "&passport=" + passport
                                            + "&adress=" + adress + "&email=" + email + "&number=" + number, false);
                                    xhr.send();
    
                                }
                            }


    соответственно на странице ты можешь иметь сколько угодно элементов которые тебя надо динамически поменять, просто добавь их в респонс result.put("тут айди хтмл элемента","тут новый текст");
    Ответ написан
  • Что означает @ManyToMany?

    @Cauac
    Java Developer
    Связь многие ко многим.
    Конкретно на вашем примере: каждый пользователь может иметь несколько ролей, и на каждую роль может назначаться несколько человек.
    Пример
    Вася имеет в вашей системе 2 роли: редактор, администратор
    В то же время в системе могут быть и другие администраторы.
    Ответ написан
    3 комментария
  • Чем можно заменить TreeMap?

    EugeneP2
    @EugeneP2
    Java Dev
    Несколько значений по одному и тому же ключу?

    А что вам мешает сделать вот так:
    Map<String, List<String>> mapOfList = new TreeMap<>();


    Еще вариант использовать
    guava multimap

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
    Ответ написан
    2 комментария
  • Каким способом зашифровать код/часть кода, что бы не смогли декомпилировать?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Никаким. На любое хитрое отверстие найдется болт с подходящей резьбой. Все будет зависеть от желания украсть. Обфусцируете - а все равно декомпилят и украдут. Будете сознательно портить код - а все равно найдут, отладят и украдут. Будете подгружать с сервера - все равно напишут псевдо-клиента, стянут и украдут.
    Да, чем выше техника защиты - тем выше должна быть квалификация взломщика. Но абсолютной защиты нет и быть не может.
    Ответ написан
    2 комментария
  • Как использовать фреймворки в IntelliJ IDEA CE?

    Можете. Просто в IDE будут отсутствовать такие фичи, как например переход между бином из кода в xml.

    А если вы студент, аспират, преподаватель и т.п. и продукт вам необходим в целях образования, или же у вас есть OpenSource-проект и для его разработки нужна IDEA, то можете получить лицензию на Unlimite совершенно бесплатно.
    Ответ написан
    Комментировать
  • Что такое "call back interface"?

    EvilsInterrupt
    @EvilsInterrupt
    System programming, Reversing Engineering, C++
    Для чего?

    Допустим ты пришел в мед.учреждение за справкой по какому-то там специалисту и к примеру справка будет делаться 4 часа. В конечном итоге ее можно будет забрать в регистратуре.

    У тебя две стратегии:
    1. Каждые 5 мин. подходить в регистратуру "А справка на фамилию Пупкина готова?"
    2. Оставить визитную карточку с телефоном на Пупкина и попросить позвонить, как будет готова справка.

    Какая стратегия более удобная? ;)

    Это принцип "Не звоните нам, мы сами вам позвоним".

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

    Код, который вызывают это callback - "Обратный вызов". Некоторые условия - это событие.

    В примере выше callback-ом является Пупкин, а событием является "справка готова".
    Ответ написан
    Комментировать
  • Как присоединить Базу данных к своему проекту на GitHub?

    EugeneP2
    @EugeneP2
    Java Dev
    Если БД не большая, то можно использовать встраиваемую (imbedded) базу данных, например H2.

    База будет подыматься вместе с вашим приложением.

    Все что нужно, это подключить в зависимости JDBC драйвер
    <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>1.4.192</version>
            </dependency>


    И указать URL с нужными параметрами

    Простой пример
    import java.sql.*;
    
    public class H2Main {
    
        static {
            try {
                Class.forName("org.h2.Driver");
            } catch (ClassNotFoundException e) {
                System.err.println("Error load H2 JDBC driver: " + e.getMessage());
            }
        }
    
    
        public static void main(String[] args) {
    
            try (Connection con = DriverManager.getConnection("jdbc:h2:./h2example", "sa", "")) {
    
                createSimpleDBSchema(con);
    
                System.out.printf("Message from H2: %s\n", getMessage(con));
    
    
            } catch (Exception e) {
                System.err.printf("%s: %s\n", e.getClass().getSimpleName(), e.getMessage());
            }
    
    
        }
    
    
        static void createSimpleDBSchema(Connection con) {
            try (Statement stmt = con.createStatement()) {
    
                stmt.executeUpdate("CREATE TABLE HelloH2 (message varchar(255) NULL);");
    
                stmt.executeUpdate("INSERT INTO HelloH2 (message) VALUES ('Hello World!')");
    
            } catch (SQLException e) {
                System.err.printf("%s: %s\n", e.getClass().getSimpleName(), e.getMessage());
            }
        }
    
    
        static String getMessage(Connection con) throws SQLException {
    
            try (Statement stmt = con.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT message FROM HelloH2")) {
    
                if (rs.next())
                    return rs.getString("message");
                else
                    return null;
    
            }
        }
    
    }
    Ответ написан
    1 комментарий
  • Как реализовать Oauth провайдер на Spring?

    Vestail
    @Vestail
    Software Engineer
    Ответ написан
    Комментировать
  • На чем пишут автомобильный софт?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    На яве делают обычно GUI + медиацентр. Да и то не всегда на яве. Сам медиациент общается с автомобилем по шине CAN, иногда, в редких случаях еще и по ethernet (привет Tesla). На шине CAN сидят бортовые компьютеры, датчики, компьютеры управления подвеской, тормозами, мотором. Всё это хозяйство может быть реализовано как в железе ПЛИС (verilog), так и на SOC (пишется на C/C++).
    В современном авто от двух до 15 компухтеров разного назначения, а то и больше.

    Вот, достаточно внятная статья - auto.howstuffworks.com/under-the-hood/trends-innov...
    Ну а вообще, по ключевому слову automotive
    O! www.cvel.clemson.edu/auto/systems/auto-systems.html - тыкаем на картинке в компоненты и читаем!
    Ответ написан
    Комментировать
  • В чем отличия redirect от requestDispatcher?

    zolt85
    @zolt85
    Программист
    И так, отличия.
    Forward:
    • выполняется непосредственно сервлетом
    • браузер абсолютно не в курсе, что происходит, и его исходный URL не меняется
    • перезагрузка страницы в браузере инициирует запрос на оригинальный URL


    Redirect:
    • состоит из двух шагов, в которых Ваше приложение говорит браузеру получить контент с другого URL, отличного от оригинального URL
    • перезагрузка страницы не инициирует запрос по оригинальному URL, а пойдет по URL из redirect
    • немного медленнее, т.к. приходится делать 2 запроса вместо одного
    • данные оригинального запроса (первого), будут недоступны второму запросу


    Проще говоря, через forward вы можете вернуть контент с другого ресурса, другую jsp. При этом исходный URL не изменится.
    Ответ написан
    4 комментария
  • Почему запрещен remove в for/in?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Потому что вы режете сук, на котором сидите.
    The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.


    List<String> names = ....
    Iterator<String> i = names.iterator();
    while (i.hasNext()) {
       String s = i.next(); // must be called before you can call i.remove()
       // Do something
       i.remove();
    }
    Ответ написан
    Комментировать
  • Как сделать, чтобы JDBC использовал мой класс для decimal полей?

    EugeneP2
    @EugeneP2
    Java Dev
    Как-то подменить возвращаемый BigDecimal методом ResultSet#getBigDecimal у вас не выйдет, так как это определено jdbc спецификацией.
    Помимо этого, BigDecimal immutable клаcc, и переопределить его не выйдет, даже если ваш класс Curr расширяет Number, вы сможете только привести их общему типу, т.е. к Number. Попытка привести BigDecimal к Curr или на оборот приведет к ClassCastException.

    Проще сделать как написал Виталий Витренко, но можно заморочиться и запроксить Driver, Connection, Statement и ResultSet и после вызова метода gеBigDecimal выполнять нужные преобразования...

    Вот такой вот велосипед :)

    Прокси псевдо драйвер, который сам регистрируется в DriverManager
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.math.BigDecimal;
    import java.sql.*;
    
    public final class PostgresDriverProxyRegister implements InvocationHandler {
    
    	static {
    		try {
    			DriverManager.registerDriver((Driver) newProxy(new org.postgresql.Driver()));
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    
    
    	public static Object newProxy(Object target) {
    		Class<?> clazz = defineInterface(target);
    		return clazz == null ? target
    				: Proxy.newProxyInstance(Driver.class.getClassLoader(), new Class[]{clazz}, new PostgresDriverProxyRegister(target));
    	}
    
    	public static Class<?> defineInterface(Object o) {
    
    		if (o == null)
    			return null;
    
    		if (o instanceof Driver)
    			return Driver.class;
    		if (o instanceof Connection)
    			return Connection.class;
    		if (o instanceof Statement)
    			return Statement.class;
    		if (o instanceof PreparedStatement)
    			return PreparedStatement.class;
    		if (o instanceof ResultSet)
    			return ResultSet.class;
    
    		return null;
    	}
    
    
    	private final Object target;
    
    	private PostgresDriverProxyRegister(Object target) {
    		this.target = target;
    	}
    
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    		String methodName = method.getName();
    
    		// в этом блоки можно делать нужные изменения для возвращаемых значений методамы ResultSet
    		if (proxy instanceof ResultSet) {
    			Object invokeResult = method.invoke(target, args);
    			if (invokeResult != null) {
    				if ("getBigDecimal".equals(methodName)) {
    					// округляем до 2-х знаков после запятой
    					BigDecimal bigDecimal = (BigDecimal) invokeResult;
    					invokeResult = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);
    				} else if ("getString".equals(methodName)) {
    					// убираем пробелы в начале и конце строки, делаем строку в верхнем регистре
    					String s = (String) invokeResult;
    					invokeResult = s.trim().toUpperCase();
    				}
    			}
    
    			return invokeResult;
    		}
    
    		if (proxy instanceof Driver) {
    			if ("acceptsURL".equals(methodName) || "connect".equals(methodName)) {
    				// меняем префикс на оригинал
    				String url = (String) args[0];
    				if (url.startsWith("jdbc:postgresql-proxy:")) {
    					args[0] = url.replace("jdbc:postgresql-proxy:", "jdbc:postgresql:");
    				}
    			}
    		}
    
    		return invokeAndProxy(method, args);
    	}
    
    	public Object invokeAndProxy(Method method, Object[] args) throws Throwable {
    		Object returnValue = method.invoke(target, args);
    		return newProxy(returnValue);
    	}
    }


    Для самой программы, работы с jdbc никак не изменится, только нужно изменить префикс url-а к БД

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
    
            Class.forName("ua.home.jdbc.driver.warp.postgres.PostgresDriverProxyRegister");
    
            try(Connection connection = DriverManager
                    // используем отличный от оригинала прификс к url 'jdbc:postgresql-proxy:', что бы именно наш драйвер грузился
                    .getConnection("jdbc:postgresql-proxy://localhost:5432/test_db", "test_user", "test_password");
                Statement statement = connection.createStatement();
                ResultSet rs = statement.executeQuery("SELECT 12.65456161 as testDecimal, '  tEsTsTrinG    ' as testString")) {
    
                if (rs.next()) {
                    System.out.printf("testDecimal = '%s'\n", rs.getBigDecimal("testDecimal"));
                    System.out.printf("testString = '%s'\n", rs.getString("testString"));
                }
    
                /* output in console
                        testDecimal = '12.65'
                        testString = 'TESTSTRING'
                */
    
            }
        }
    }
    Ответ написан
    1 комментарий
  • Как сгенирировать первичный ключ в jpa?

    EugeneP2
    @EugeneP2
    Java Dev
    @GeneratedValue(strategy = GenerationType.IDENTITY)


    или вот 1 или 2
    Ответ написан
    Комментировать
  • Как лучше убрать повтороение кода?

    maaGames
    @maaGames
    Погроммирую программы
    bool isExecuting()
    {
    return mGetRequest != null && mGetRequest.isExecuting();
    }
    Ответ написан
    2 комментария