Задать вопрос
  • В чем разница внедрения зависимостей по ссылке или по значению?

    EugeneP2
    @EugeneP2
    Java Dev
    value - для примитивов, стрингов, ${пропертей} и #{Spring Expression Language}.
    ref - если нужно заинжектить бин. В ref указывается id бина
    Ответ написан
    Комментировать
  • Где можно почитать о class-loader?

    EugeneP2
    @EugeneP2
    Java Dev
    Комментировать
  • Чем можно заменить 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 комментария
  • Как вывести матрицу в окно??

    EugeneP2
    @EugeneP2
    Java Dev
    Что за окно? Окно веб браузера, или окно swing? Или консоль?

    Если swing, можно использовать JTable: How to Use Tables
    Ответ написан
  • Для чего используется BindingResult в java?

    EugeneP2
    @EugeneP2
    Java Dev
    Из него мы можем узнать были ли ошибки валидации и какие при байденге http запроса на объект в контроллере

    Например, вот такой у нас контроллер
    @Controller
    public class SearchCommentController {
    
    	...................
    
    	@RequestMapping(method = RequestMethod.POST)
    	public String displayCommentAlert(@Validated FormParams params, BindingResult bindingResult, Model model) {
    		if (bindingResult.hasErrors() == false) {
    			List<CommentWithPeopleDetail> foundComments = commentDao.find(params);
    			model.addAttribute("foundComments", foundComments);
    		}
    		return "commentAlert";
    	}
    
    	...................
    }


    bindingResult инжектится спригом в метод контроллер

    вот валидатор
    public class SearchCommentParamValidator implements Validator {
    
    	@Override
    	public boolean supports(Class<?> clazz) {
    		return FormParams.class.isAssignableFrom(clazz);
    	}
    
    	@Override
    	public void validate(Object target, Errors errors) {
    
    		FormParams params = (FormParams) target;
    
    		if (StringUtils.isBlank(params.getRuleId()) && StringUtils.isBlank(params.getRef())) {
    			errors.reject(null, "Необходимо указать или 'ID правила', и/или 'Объект алерта'!");
    		} else if (params.getDateFrom() == null || params.getDateTo() == null) {
    			errors.reject(null, "Необходимо указать период поиска!");
    		}
    	}
    }
    Ответ написан
    Комментировать
  • Как отправить введенные данные пользователя в метод и вернуть результат?

    EugeneP2
    @EugeneP2
    Java Dev
    int factorial = Main.number(number);
                System.out.print(factorial);
    Ответ написан
    Комментировать
  • Почему не подхватывается Converter?

    EugeneP2
    @EugeneP2
    Java Dev
    Сам бин conversionService нужно указать в <mvc:annotation-driven/>

    Conversion and Formatting

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set merge="true">
                <bean class="my.app.OptionConverter"/>
            </set>
        </property>
    </bean>
    
      <mvc:annotation-driven conversion-service="conversionService"/>
    Ответ написан
    5 комментариев
  • Как присоединить Базу данных к своему проекту на 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 комментарий
  • Сортирование матрицы (двухмерного массива) Java?

    EugeneP2
    @EugeneP2
    Java Dev
    Если вы планируете сортировать матрицу, то конечно эффективней будет хранить её в виде одномерного массива, чтоб можно было эффективно отсортировать его с помощью быстрой сортировки реализованной методе sort в класса java.util.Arrays.

    А чтоб с массивом можно было работать как с матрицей, можно реализовать класс-адаптер
    import java.util.Arrays;
    
    public class IntMatrix {
    		private final int[] lineMatrix;
    		private final int n;
    		private final int m;
    
    		public IntMatrix(int[] lineMatrix, int n, int m) {
    
    			if (n < 0 || m < 0 || lineMatrix.length != n * m)
    				throw new IllegalArgumentException();
    
    			this.lineMatrix = lineMatrix.clone();
    			this.n = n;
    			this.m = m;
    		}
    
    		public int get(int i, int j) {
    			if (i < n && j < m)
    				return lineMatrix[i * m + j];
    			else
    				throw new ArrayIndexOutOfBoundsException();
    		}
    
    		public void set(int value, int i, int j) {
    			if (i < n && j < m)
    				lineMatrix[i * m + j] = value;
    			else
    				throw new ArrayIndexOutOfBoundsException();
    		}
    
    		public  void sort() {
    			// готовая реализация быстрой сортировки
    			Arrays.sort(lineMatrix);
    		}
    
    		public int getN() {
    			return n;
    		}
    
    		public int getM() {
    			return m;
    		}
    	}


    Пример использования
    public static void main(String[] args) {
    
    
    		int n = 10, m = 15;
    
    		IntMatrix intMatrix = new IntMatrix(new int[n * m], n, m);
    
    		fillMatrixByRandomValues(intMatrix);
    
    		printMatrix(intMatrix);
    
    		intMatrix.sort();
    
    		System.out.println("---------------");
    
    		printMatrix(intMatrix);
    	}
    
    
    	/** заполнение матрицы случайными числами */
    	static void fillMatrixByRandomValues(IntMatrix matrix) {
    		Random random = new Random();
    		for (int i = 0; i < matrix.getN(); i++) {
    			for (int j = 0; j < matrix.getM(); j++) {
    				matrix.set(random.nextInt(1000), i, j);
    			}
    		}
    	}
    
    	/** печать матрицы в консоль */
    	static void printMatrix(IntMatrix matrix) {
    		for (int i = 0; i < matrix.getN(); i++) {
    			for (int j = 0; j < matrix.getM(); j++) {
    				System.out.printf("%s\t", matrix.get(i , j));
    			}
    			System.out.println();
    		}
    	}


    Линейный массив будет занимать меньше места, чем двумерный. Сортировка реализованная в классе java.util.Arrays хорошо и по скорости и по расходу памяти.
    Ответ написан
    3 комментария
  • Как переправить пользователя на страницу 404?

    EugeneP2
    @EugeneP2
    Java Dev
    Ответ написан
    Комментировать
  • Что собой представляет Java EE (Web) приложение?

    EugeneP2
    @EugeneP2
    Java Dev
    да, интернет банкинг, если он написан на джаве.

    В основном это внутрикорпоративные решение связанные с финансами, типа процессинг транзакций, документооборот, обработка заявок... Если хотите какие-то примеры, смотрите в сторону банков.

    Сервлеты, серверы приложений, сервлет контейнеры, JPA, JMS, база данных, очереди, транзакции, Spring, Hibernate - видите эти слова, это Java EE приложение:)

    Та просто, допустим интернет магазин, например будет сервер Tomcat (сервлет контейнер), скорее всего Spring, база данных + какая нибудь реализация JPA, скорее всего Hibernat. Или вместо реляционной БД, будет Mongodb. Вот это вам и будет Java EE
    Ответ написан
  • Как установить связь между jpa и ajax?

    EugeneP2
    @EugeneP2
    Java Dev
    onclick="unblock(<%=contracts.get(i).getNumber();%>)" в дескриптере пропустили знак равно.

    function unblock() { - наверно функция должна принимать number или id?

    function unblock(id) {

    Сообщить об успешности или не успешности операции на сервере можно с помощью кода статуса в ответе от сервера.

    Например операция удаления

    Сервлет
    @WebServlet("/test")
    public class TestServlet extends HttpServlet {
    
        private static final Logger LOG = LoggerFactory.getLogger(TestServlet.class);
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.getRequestDispatcher("/test.jsp").forward(req, resp);
        }
    
        @Override
        protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            try {
                long id = Long.parseLong(req.getParameter("id"));
                testRemove(id);
                resp.setStatus(200);
            } catch (Exception e) {
                LOG.error("Error remove: {}", e.getMessage());
                resp.setStatus(500);
            }
        }
    
        private void testRemove(long id) {
            if (id < 1) {
                throw new RuntimeException("id can't be < 1");
            }
        }
    }


    JSP старница
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    
    <p>
        <input type="button" value="remove data (OK)" onclick="remove(2)"/>
    </p>
    
    
    <p>
        <input type="button" value="remove data (ERROR)" onclick="remove(-1)"/>
    </p>
    
    
    <script>
        function remove(id) {
    
            var request = new XMLHttpRequest();
    
            request.open('DELETE', '/test?id=' + id, false);
            request.send();
    
            if (request.status == 200) {
                alert('Данные упешно удалены')
            } else {
                alert('Ошибка удаления данных!');
            }
        }
    </script>
    
    </body>
    </html>
    Ответ написан
  • Как правильно сложить две строки?

    EugeneP2
    @EugeneP2
    Java Dev
    for (int i = 0; i < b.length(); i++); точка запятая тут не нужна
    Ответ написан
  • Как в jsp привязать удалить определенный элемент из таблицы?

    EugeneP2
    @EugeneP2
    Java Dev
    1. JSP скриплеты - это очень плохой тон и не рекомендуется делать.

    Это нужно делать в сервлете (не в jsp)
    ContractServiceImpl contractService = new ContractServiceImpl();
         List<Contract> contracts = contractService.getAllContractsForUser(user.getUserId());


    потом contracts передавать в jsp через атрибут реквеста

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         ContractServiceImpl contractService = new ContractServiceImpl();
         List<Contract> contracts = contractService.getAllContractsForUser(user.getUserId());
    
       request.setAttribute("contracts",contracts);
       RequestDispatcher requestDispatcher; 
       requestDispatcher = request.getRequestDispatcher("/you_jsp_page.jsp");
      requestDispatcher.forward(request, response);
    }


    и потом уже на стороне JSP с помощью JSTL выводить данные
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <hmtl>
    ...
    <body>
    <table>
    <c:forEach items="${contracts}" var="contr">
    <tr>
       <td>${contr.name}</td>
       <td>${contr.number}</td>
    
      ....
    </tr>
    </c:forEach>
    </table>
    </body>
    </hmtl>


    2. Если пока не хотите заморачиваться с JavaScript-ом и AJAX-ом, то есть более простой вариант с формой.

    а) у сущности Contract должен быть уникальный id, по которому вы могли бы удалить/выбрать/изменить его.

    б) в JSP вашу таблицу в тег и добавьте еще один столбец с чекбоксом, у которого в качестве value будит id Contract-а. Добавить кнопку "Удалить выбранное".

    <form method="post" action="ваш сервлет">
    <input type="submit" value="Удалить выбранное"/>
    <table>
    <c:forEach items="${contracts}" var="contr">
    <tr>
       <td><input type="checkbox" name="id" value="${contr.id}"/></td>
       <td>${contr.name}</td>
       <td>${contr.number}</td>
    
      ....
    </tr>
    </c:forEach>
    </table>
    </form>


    с) Реализовать в вашем сервлете метод обработки пост запросов где получите из реквеста выбранные Id и выполните удаление.

    @Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    		String[] ids = req.getParameterValues("id");
    
    		if (ids != null && ids.length > 0) {
    			ContractServiceImpl contractService = new ContractServiceImpl();
    			contractService.removeAll(ids);
    		}
    
    		doGet(req, resp); 
    	}


    doGet(req, resp); - метод реализован выше. Произойдет новая выборка контрактов, только уже без удаленных и передастся в JPS. Обновится страница
    Ответ написан
    Комментировать
  • Есть ли в Java/Spring транзакции на изменение объектов?

    EugeneP2
    @EugeneP2
    Java Dev
    1-й вариант: Не использовать изменяемый объект, а каждый раз, когда вы хотите поменять что-то, создавать новый объект, при этом, сам объект должен быть immutable. Доступ к объекту осуществлять через фабрику. Такое решение имхо будит наиболее правильным.

    Пример:

    immutable класс

    public final class User {
    
    	private final String login;
    	private final Date dateCreate;
    	private final String description;
    	private final Set<String> roles;
    
    	public User(String login, Date dateCreate, String description, Set<String> roles) {
    		this.login = login;
    		this.dateCreate = (Date) dateCreate.clone();
    		this.description = description;
    		this.roles = Collections.unmodifiableSet(roles);
    	}
    
    	public String getLogin() {
    		return login;
    	}
    
    	public Date getDateCreate() {
    		return (Date) dateCreate.clone();
    	}
    
    	public String getDescription() {
    		return description;
    	}
    
    	public Set<String> getRoles() {
    		return roles;
    	}
    }


    Фабрика

    public class UserFactory<T> {
    
    	private final AtomicReference<T> atomicReference;
    
    	public UserFactory(T object) {
    		this.atomicReference = new AtomicReference<>(object);
    	}
    
    	public T getObject() {
    		return atomicReference.get();
    	}
    
    	public void setObject(T object) {
    		atomicReference.set(object);
    	}
    }


    public static void main(String[] args) {
    
    		User user = new User("user1", new Date(), "test user", new HashSet<>(Arrays.asList("READ", "ADD")));
    
    		UserFactory<User> userFactory = new UserFactory<>(user);
    
    		exampleUsingUser(userFactory);
    
    	}
    
    	public static void exampleUsingUser(UserFactory<User> userFactory) {
    
    		User user = userFactory.getObject();
    
    		System.out.println(user.getLogin());
    		System.out.println(user.getDescription());
    		System.out.println(user.getRoles());
    	}


    2-й вариант: эдакий велосипед:) Контролировать доступ через прокси с использованием ReentrantReadWriteLock

    Пример:

    Для начала нам нужно выделить интерфейс класса, состояние объекта которого будет меняться

    public interface Settings {
    
    	String getColor();
    	void setColor(String color);
    
    	String getDescription();
    	void setDescription(String description);
    
    	int getSize();
    	void setSize(int size);
    }


    Реализуем интерфейс

    public class SettingsImpl implements Settings {
    
    	private volatile String color;
    	private volatile String description;
    	private volatile int size;
    
    
    	public static Settings newSettings() {
    		return ProxySettingsKeeper.createProxy(new SettingsImpl());
    	}
    	
    	private SettingsImpl() {
    	}
    
    	@Override
    	public String getColor() {
    		return color;
    	}
    
    	@Override
    	public void setColor(String color) {
    		this.color = color;
    	}
    
    	@Override
    	public String getDescription() {
    		return description;
    	}
    
    	@Override
    	public void setDescription(String description) {
    		this.description = description;
    	}
    
    	@Override
    	public int getSize() {
    		return size;
    	}
    
    	@Override
    	public void setSize(int size) {
    		this.size = size;
    	}
    }


    Прокси

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class ProxySettingsKeeper implements InvocationHandler {
    
    	private final Settings settings;
    
    	private final ReentrantReadWriteLock.ReadLock readLock;
    	private final ReentrantReadWriteLock.WriteLock writeLock;
    
    	public ProxySettingsKeeper(Settings settings) {
    
    		ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    		this.readLock = readWriteLock.readLock();
    		this.writeLock = readWriteLock.writeLock();
    
    		this.settings = settings;
    	}
    
    	public static Settings createProxy(Settings settings) {
    		return (Settings) Proxy.newProxyInstance(settings.getClass().getClassLoader()
    				, new Class[]{Settings.class}
    				, new ProxySettingsKeeper(settings));
    	}
    
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    		String name = method.getName();
    
    		if (name.startsWith("get")) {
    
    			readLock.lock();
    			try {
    				return method.invoke(settings, args);
    			} finally {
    				readLock.unlock();
    			}
    
    		} else if (name.startsWith("set")) {
    
    			writeLock.lock();
    			try {
    				return method.invoke(settings, args);
    			} finally {
    				writeLock.unlock();
    			}
    		}
    
    		return method.invoke(settings, args);
    	}
    }


    public static void main(String[] args) {
    
    		Settings settings = SettingsImpl.newSettings();
    
    		settings.setDescription("test");
    
    		System.out.println(settings.getDescription());
    	}
    Ответ написан
  • Есть ли в Spring своя библиотека для делания HTTP запросов?

    EugeneP2
    @EugeneP2
    Java Dev
    RestTemplate

    находится в пакете spring-web
    Ответ написан
    Комментировать
  • К какой спецификации относится выражение %{...} в JSP?

    EugeneP2
    @EugeneP2
    Java Dev
    Вообще то не %{...}, а ${...}.

    По моему они появились в версии JSP 2.0
    Ответ написан