четверг, 2 марта 2017 г.

Модальные глаголы


Модальные глаголы - это вспомогательные глаголы, которые выражают возможность, вероятность, необходимость того или иного действия.
К модальным глаголам относятся: can, could, may, might, must, will, would, shall, should, ought to.
Основные характеристики:

  1. Модальные глаголы не имеют окончания -s  в единственном числе. She must go to work every day.
  2. Модальные глаголы не изменяются по временам. She can go with us. (Она сможет пойти с нами). You must keep it a secret. (Ты должен держать это в секрете.)
  3. Модальные глаголы сами формируют вопросительную или отрецательную форму. May I use your phone? Tim shouldn't smoke so much.
  4. После модальных глаголов никогда не идет to. He may know about it.

Can

Can выражает способность или возможность выполнять действие и переводится как "могу, умею".
Используется:
  1. Для отражения физической или умственной способности. Can I borrow your pen, please?
  2. Для обозначения общей возможности/способности: Sally thinks her sister can be anywhere right now.
  3. Для того, чтобы попросить/дать разрешения. Can I come in?
  4. Для запрещения чего либо. You can’t use your cell phone here.
  5. Для выражения сильного недоверия, удивления в отрицательных (can’t) и вопросительных предложениях (Сan….?). Сan’t... переводится выражениями: не может быть; не может быть, чтобы; невероятно. Can… переводится выражением: Неужели….?Can/can’t + глагол выражает действие, относящееся к настоящему. He cannot be there! Он не может там быть! Can/can’t + Present Perfect выражает действие, относящееся к прошлому. Can you have seen this film? Неужели ты видел этот фильм?
  6. С глаголами see, hear, feel, smell, taste при условии, что действие происходит в настоящий момент (now). В этом случае can на русский язык не переводится. I can smell something burning. Я чувствую, что что-то горит.
Чтобы образовать предложение с CAN необзодимо воспользоваться схемой:

Местоимение/Существительное + Модальный глагол + Глагол без to + Остальные слова

Наречия never, seldom, often, usually, always стоят после can.
He can always answer the question

Наречия once a month, four times a year и т.д. ставятся в конце предложения.
Jessica can go to the museum twice a week.

Чтобы составить общий вопрос, глагол can необходимо поместить в начало предложения.
Can Sara go to London?
Вопросительное слово ставиться перед вспомогательным глаголом can.
When can they come?

Образование отрецания с can:

Местоимение/существительное +  модальный глагол + not + глагол без to + остальные слова

Можно использовать полную форму cannot(без пробела) или сокращенную can't
George cannot understand the rule.

Could

В прошедшем времени у глагола CAN есть форма COULD, переводится как мог, имел возможность
I could hear something. Я мог что-то расслышать.
Образуется:

Местоимение/Существительное + Модальный глагол + Глагол без to + остальные слова

Вопрос:

Модальный глагол + Местоимение/Существительное + Глагол без to + остальные слова


Отрицание

Местоимение/Существительное + Модальный глагол +not+ Глагол без to + остальные слова

Использование:
  1. В качестве формы can в прошедшем времени
  2. В настоящем и будущем времени с частицей БЫ, мог бы
  3. В сочетании с Present Perfect(have done), чтобы сказать о том, что могло бы произойти но не произошло по отношению к прошлому. I didn’t know that you wanted to go to the cinema. I could have got you a ticket. Я не знал, что ты хотел пойти в кино. Я мог бы купить тебе билет.
  4. В сочетании с Present Perfect(have done),чтобы сказать о том, что было бы невозможно по отношению к прошлому. It wasn’t true. She couldn't have said that. Это было неправдой. Не может быть, чтобы она сказала это.
  5. В сочетании с Present Perfect(have done) в вопросительном предложении, чтобы выразить сильное сомнение, недоверие по отношению к прошлому. Could they have left yesterday? Неужели они уехали вчера?

Be able to

Употребление
  1. Заменяет can в будущем времени, переводится как смочь. I’ll be able to speak Spanish fluently by the end of the year.
  2. Так же употребляется в прошедшем времени в утвердительной форме, когда идет речь о конкретном событии. Jim and Pete had a game of tennis yesterday. Pete played very well, but Jim was able to beat him. Джим и Пит играли в теннис вчера. Пит играл очень хорошо, но Джим смог его победить.
  3. can нельзя употреблять в будущем времени для обозначения физической или умственной возможности/способности, для этого мы употребляем оборот be able to: He will be able to walk in two days.

вторник, 28 февраля 2017 г.

Вызов Rest сервиса в Java

Рассмотрим способо обращения к Rest-сервису, на примере микросервисов. Так же в скользь будет рассмотрен способ избежения дублирования кода в микросервисах. Я использую данную статью, позже, планирую ее перевести.

Первым делом реализуем библиотечную часть, которая будет использоваться во всех частях микросервиса для обмена.
package com.example.user.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by bartoszjedrzejewski on 08/06/2016.
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserView {

    private long id;
    private String forename;
    private String surname;
    private String organisation;
    private List notifications;
    private long points;

    public UserView(){

    }

    public long getId() {
        return id;
    }

    public String getForename() {
        return forename;
    }

    public String getSurname() {
        return surname;
    }

    public String getOrganisation() {
        return organisation;
    }

    public List getNotifications() {
        return notifications;
    }

    public long getPoints() {
        return points;
    }
}

и pom-файл для мавена:

    4.0.0

    com.example
    user-client-libs
    0.0.1-SNAPSHOT
    
        
            com.fasterxml.jackson.core
            jackson-annotations
            2.6.6
        
    



Чтобы была возможность использовать данный класс, необходимо выполнить в консоли mvn clean install


Теперь рассмотрим микросервис, предоставляющий информацию о пользователе.

Пользователь:
package com.example;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by bartoszjedrzejewski on 08/06/2016.
 */
public class User {

    private final long id;
    private final String forename;
    private final String surname;
    private final String organisation;
    private final List notifications;
    private final long points;
    //Friends are deprecated and should not be used
    private final List friends;

    public User(int id) {
        String[] forenames = {"Alice", "Manjula", "Bartosz", "Mack"};
        String[] surnames = {"Smith", "Salvatore", "Jedrzejewski", "Scott"};
        String[] organisations = {"ScottLogic", "UNICEF"};

        forename = forenames[id%3];
        surname = surnames[id%4];
        organisation = organisations[id%2];
        notifications= new ArrayList<>();
        notifications.add("You have been promoted!");
        notifications.add("Sorry, disregard the previous notifaction- wrong user");
        points = id * 31 % 1000;

        //You have no friends
        friends = new ArrayList<>();

        this.id = id;
    }

    public long getId() {
        return id;
    }

    public String getForename() {
        return forename;
    }

    public String getSurname() {
        return surname;
    }

    public String getOrganisation() {
        return organisation;
    }

    public List getNotifications() {
        return notifications;
    }

    public long getPoints() {
        return points;
    }

    public List getFriends() {
        return friends;
    }
}

Обычный Rest-контроллер:
package com.example;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by bartoszjedrzejewski on 08/06/2016.
 */
@RestController
public class UserController {

    @RequestMapping("/user")
    public User getUser(@RequestParam(value="id", defaultValue="1") int id) {
        return new User(id);
    }

}
И запускалочка от SpringBoot:
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UserServiceApplication {

 public static void main(String[] args) {
  SpringApplication.run(UserServiceApplication.class, args);
 }
}

Для настройки порта используется файл application.properties.Укажем в нем: server.port = 9001

pom-файл:

 4.0.0

 com.example
 user-service
 0.0.1-SNAPSHOT
 jar

 user-service
 Demo user-service with Spring Boot

 
  org.springframework.boot
  spring-boot-starter-parent
  1.3.5.RELEASE
   
 

 
  UTF-8
  1.8
 

 
  
   org.springframework.boot
   spring-boot-starter-web
  
  
   org.springframework.boot
   spring-boot-starter-test
   test
  
  
   com.fasterxml.jackson.core
   jackson-databind
   2.5.0
  
 


 
  
   
    org.springframework.boot
    spring-boot-maven-plugin
   
  
 
 




Простенький Rest-контроллер, который обращается к выше описанному микросервису:
package com.example;

import com.example.user.dto.UserView;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * Created by bartoszjedrzejewski on 09/06/2016.
 */
@RestController
public class UserDashboardController {

    @RequestMapping("/dashboard")
    public String getUser(@RequestParam(value="id", defaultValue="1") int id) {
        RestTemplate restTemplate = new RestTemplate();
        UserView user = restTemplate.getForObject("http://localhost:9001/user?id="+id, UserView.class);
        return "USER DASHBOARD 
" +
                "Welcome " + user.getForename() +" "+user.getSurname()+"
"+
                "You have " +user.getPoints() + " points! Good job!
"+
                "
"+
                "
"+user.getOrganisation();
    }

}
Запускалочка:
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UserDashboardApplication {

 public static void main(String[] args) {
  SpringApplication.run(UserDashboardApplication.class, args);
 }
}

порт: server.port = 9002

pom-файл:

 4.0.0

 com.example
 user-dashboard
 0.0.1-SNAPSHOT
 jar

 user-dashboard
 Demo user-dashboard service with Spring Boot

 
  org.springframework.boot
  spring-boot-starter-parent
  1.3.5.RELEASE
   
 

 
  UTF-8
  1.8
 

 
  
   org.springframework.boot
   spring-boot-starter-web
  
  
   org.springframework.boot
   spring-boot-starter-test
   test
  
  
   com.example
   user-client-libs
   0.0.1-SNAPSHOT
  
 
 
 
  
   
    org.springframework.boot
    spring-boot-maven-plugin
   
  
 
 



Вот и все, что нужно для обращения к Rest сервису. Все за нас делает объект RestTemplate. Конечно же можно выполнять не только Get запросы, но и post (postForObject(URI url, Object request, Class responseType )), put, delete. Подробности здесь.

пятница, 24 февраля 2017 г.

Дебаг Soap

Чтобы получить тело сообщения в лог необходимо:

  1. для класса вебсервиса добавить аннотацию @HandlerChain с параметром file="handler.xml"
  2. в handler.xml нужно указать на класс-хэндлер, который и будет выводить сообщение в лог:
    
      
        
          org.Handler
          org.Handler
    
  3. И его реализация:
    public class Inflate implements SOAPHandler {
    
        public boolean handleMessage(SOAPMessageContext mc) {
            try {
                SOAPMessage message = mc.getMessage();
                message.writeTo(System.out);
                return true;
            } catch (SOAPException e) {
                return false;
            }
        }
    }
    
Взято здесь

воскресенье, 5 февраля 2017 г.

Кастомные аннотации в спринг

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

package com.calculator;

public interface Calculator {
    int sum(int a, int b);
    int sub(int a, int b);
}


И его реализация:
package com.calculator;
import org.springframework.stereotype.Component;

@Component
@Profiling
public class CalculatorImpl implements Calculator {
    @Override
    public int sum(int a, int b) {
        return a + b;
    }

    @Override
    public int sub(int a, int b) {
        return a - b;
    }
}


Нас интересует новая аннотация @Profiling, которую мы и будем рализовывать. Для этого создадим следующий интерфейс:

package com.calculator;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Profiling {
}

Если у аннотации должны быть какие то параметры - создаются обычные филды, но это не наш случай. Так же необходимо обратить внимание на аннотацию @Retention(RetentionPolicy.RUNTIME) . Ее основное назначение - указать, как долго необходимо хранить данную аннотацию. Бывают следующие значния:

  • RetentionPolicy.SOURCE - аннотация используется на этапе компиляции и должна отбрасываться компилятором.
  • RetentionPolicy.CLASS - аннтоация будет записана в class-файл компилятором, но не должна быть доступна во время выполнения.
  • RetentionPolicy.RUNTIME - аннотация будет записана в class-файл и доступна во время выполнения.
Для данной аннотации значение по умолчанию CLASS. Для нас подходит только RUNTIME. 
Аннотация готова, но про нее ничего не знает сам спринг. Чтобы их познакомить необходимо создать BeanPostProcessor, для обработки данной аннотации.

package com.calculator;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Component
public class ProfilingAnnotationBeanPostProcessor implements BeanPostProcessor {
    private Map<String, Class>map = new HashMap<>();
    @Override
    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
        if (bean.getClass().isAnnotationPresent(Profiling.class)){
            map.put(s,bean.getClass());
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
        Class beanClass = map.get(s);
        if (beanClass != null){
            return Proxy.newProxyInstance(beanClass.getClassLoader(), beanClass.getInterfaces(),
                    (proxy, method, args) -> {
                        System.out.println("method:" + method.getName());
                        System.out.println("params:" + Arrays.toString(args));

                        return method.invoke(bean, args);
            });
        }
        return bean;
    }
}

в BeforeInitialization мы запоминаем те бины, которые помечены аннотацией, а в AfterInitialization, проверяем, если это запомненный бин, добавляем логирование. Ну и осталось создать контекст спринга, в котором нет ничего особенного:



и запуск:
package com;

import com.calculator.Calculator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;


public class App2 {
    public static void main(String[] arg){
        ApplicationContext context = new GenericXmlApplicationContext("context.xml");
        Calculator calc = context.getBean(Calculator.class);
        System.out.println(calc.sum(5,4));
        System.out.println(calc.sub(5,4));

    }


}

следующий вовод:
Connected to the target VM, address: '127.0.0.1:61942', transport: 'socket'
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Disconnected from the target VM, address: '127.0.0.1:61942', transport: 'socket'
method:sum
params:[5, 4]
9
method:sub
params:[5, 4]
1

Process finished with exit code 0


Process finished with exit code 0

воскресенье, 29 января 2017 г.

Условные предложения

Каждый раз, когда мы строим предложение с if, необходимо употребить один из 3х типов:

  1. Предложение будет состоять из Present Simple + Future Simple. We will play tennis if the rains stops. If I see him tonight, I'll tell him the truth. IF + Present Simple = Условие, Future Simple = Результа.
  2. Воображаемые ситуации, которые противоречат реальности и то, что они произойдут - маловероятно. И переводятся такие предложения с частицами бы. What would you do if you won a million pounds? Схема: IF + Past Simple (did/were/found) = Возможное условие. Future in the Past (would + глагол без to) = Возможный результат. Вместо would можно использовать глаголы could или might. If I had more time, I could come next Friday.
  3. Свое отношение к нереальным действиям. Для таких предложения нам понадобится глагол would (Future Perfect in the Past =  нереальный результат) и Past perfect (IF + PP = Нереальное условие). If you had warned me about the danger, I would not have participated in this competition. Если бы ты предупредил меня об опасности, я бы не участвовал в этих соревнованиях

понедельник, 23 января 2017 г.

Future in the Past

Future Simple in the Past

Используется:

  1. Нужно поставить глагол will в прошедшее время would. Yesterday she said, she would arrive in the evening. But unfortunately, she didn't. I knew that Alex would make dinner. В тот момент, когда речь шла о ужине, это было будущим событием: действие make dinner является будующим, для определенного момента в прошлом - I knew.
  2. Чаще всего используюутся глаголы: said, told, thought, knew, realized, expected, hoped.
Примеры:
I knew you would hepl me.
We hoped, that the train would arrive on time.
She realized, that she would not come on time.
I knew that they wouldn't understand me

The Future Continuous in the Past

Используется

  1. Если событие, которое происходило в определенное время в будующем и было будующим в какой то момент в прошлом, а в настоящий момент оно уже будущим не является. At the time, I thought that I would be studying for my math exam but I suddenly got ill and had to use  my crib notees. В то время, я думал, что буду готовиться к экзамену по математике , но вдруг заболел и мне пришлось воспользоваться шпаргалками.
Примеры:
I thought, that I would be jogging at that time.


The Future Perfect in the Past

Используется:
  1. Когда действия, которые будут закончены к определенному моменту времения в будущем, являются будущими только с точки зрения определённого момента в прошлом. I thought that I would have finished that project by the end of the day, but it took longer than I expected.
Примеры:
I thought that I would have studied all English tenses by the end of the month, but I didn't.
He expected that they would have prepared his order by 10 o’clock, but they forgot.
He knew that he would not have read the book by Saturday.

The Future Perfect Continuous in the Past

Используется:
  1. Если действие, которое будет продолжаться какое-то время в будущем и оно является будущим, только с точки зрения  определенного момента в прошлом.
Примеры:
She said that by next Easter she would have been working here for two years.
We realized that we would have been renovating a flat for half a year by the following Saturday.


Past Continuous for Future in the Past

Используется:
  1. Если вы говорите о таких запланированных действиях, которые уже «устарели» и не являются будущими к моменту речи. I got off early on Monday because I was meeting the doctor. В понедельник я ушёл пораньше с работы, потому что ходил на приём к врачу.
Примеры:
We were so busy with shopping as our son was starting school in a week then.
He couldn’t stay for dinner because he was taking his son to English classes at 5 p.m.
We were planning to dine outside, but it started raining.

воскресенье, 22 января 2017 г.

Структура Spring

Рассмотрим как происходит запуск контекста у Spring.

Превым делом должно быть какое-то описание для бинов, например xml. Для каждого описания есть BeanDefinitionReader, он парсит документ, складывает связку ид бина и бин дифинишинов. Далее Bean Factory из описания бинов первым делом создает бины, которые имплимитируют интерфейс BeanPostProcessor, с помощью этих бинов будет проиходить настройка бинов, отвечающих за бизнес-логику. Инициализация происходит следующим образом: каждый бин (только синглтон) проходит по всему списку BPP, далее вызывается инит метод у бина и бин второй раз проходит по списку BPP. На этом настройка бина завершена и он готов к использованию.