1. 혹시나 남아 있는 mysql의 흔적 지우기.

1-1 폴더 삭제. 제어판에서 mysql이라고 시작되는거 싹 지우기.

1-2.검색에서 win+R 단축키 > %appdata% 개인설정 폴더 나옴. 거기서 mysql폴더 삭제

1-3 port 번호 확인. 전에 설치했다 삭제 했다 반복 이력이 있었는데 port잡혀있었음

     cmd에서 netstat -ano | find "3306"선택하면 PID 가나오고

      cmd 에서 resmon.exe확인하면 리소스 모니터 나오고 여기서 mysql3306의  PID를 확인함

      cmd를 관리자 모드로 들어가서 taskkill /F /PID [PID 번호} 누르면 삭제됐다고 메세지...

    https://dana-study-log.tistory.com/entry/MySQL-MySQL-%EC%84%A4%EC%B9%98-3306-Port-%EC%98%A4%EB%A5%98

 

[MySQL] MySQL 설치 3306 Port 오류

오류 메시지 MySQL을 설치하는 중에 네트워크 설정시 port 설정에서 오류가 발생했다. 오류 메세지는 아래와 같았다. "the specified port already in use" 원인 MySQL은 기본 설정으로 127.0.0.1주소의 3306번의

dana-study-log.tistory.com

 

 

이과정을 하고 다시 설치 했던. 그렇게 안뜨떤 #developer default 모드가 뜬다....신기할세 

뭐가 자꾸 중간과정에 오류가 2번이상 나면 일단 모두 삭제 후 재설치 가 답이였음..ㅠㅠ

 

 

너무 길면 보기 싫기도 하고 나도 나중에 찾기 어렵고.....해서 좀 쪼갰습니다.

3. controller는 2가지로 볼수가 3가지로 볼수가 있습니다. 처음 화면 이동은 HomeContrller가 이건 뭐 비슷들 하니깐...pass

  그다음 채팅방 입장을 위해서와 여러가지 로직들을 처리하는 ChatContrller와  채팅의 websocket을 위한 controller 로 볼수 있습니다.

이 websocket은

@Component
@ServerEndpoint(value="/chatting", configurator = CustomSpringConfigurator.class)
public class WebSocketChatt {


    @Autowired
    public ChatRedisRepository repo;

    private static Set<Session> clients = Collections.synchronizedSet(new HashSet<Session>());

    public WebSocketChatt() {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
    }

    @OnMessage
    public void onMessage(Session session, String message) throws Exception {
        // 메시지 처리 로직 작성
        System.out.println("receive WebSocketChatt message : " + message);

        // ChatDto 객체 생성
        ObjectMapper objectMapper = new ObjectMapper();
        ChatDto chatDto = objectMapper.readValue(message, ChatDto.class);


        // ChatDto 객체를 Redis에 저장
        try {
            repo.save(chatDto);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("에러  : " + e.getMessage());
        }

        for (Session s : clients) {
            System.out.println("send data : " + message);
            s.getBasicRemote().sendText(message);
        }
    }

    //클라이언트가 접속할때
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("open session : " + session.toString());
        if(!clients.contains(session)) {
            clients.add(session);
            System.out.println("session open : " + session);
        }else {
            System.out.println("이미 연결된 session 임!!!");
        }

    }

    @OnClose  //클라이언트 종료시,,,브라우저 끄러나 다른 경로 갈때.
    public void onClose(Session session) {
        System.out.println("session close : " + session);
        repo.findChatList();
        clients.remove(session);
    }
}

여기서 저를 3일이나 괴롭혔던

@ServerEndpoint

@Autowired
public ChatRedisRepository repo;

나옵니다. ... AutoWired를 해결하면 serverEndopoint가 안되고 serverEndopoint가 되면 autoWired가 안되는 짜증나는 상황에서 chatGPT3는 저를 악의 구렁텅이로 밀어 넣었어요....그래서 더 3일이나 걸린듯합니다.ㅠㅠ

마지막에 그냥 구글 선배님 글 검색했습니다....선배님들 최고예요!!!!!!!

이걸 해결한것이 아까 2번의

@ServerEndpoint(value="/chatting", configurator = CustomSpringConfigurator.class)

입니다. 클래스는 2번 스토리에 있어요...^^  springboot, webSocket, Redis. chat --2. 설정 및 DTO :: 미치게힘든코딩 (tistory.com)at --2. 설정 및 DTO ::

 

springboot, webSocket, Redis. chat --2. 설정 및 DTO

1. 웹소켓을 통해 채팅 프로그램 만들기...1에서 왠만한건 다 복붙해서 이런건 감사... 2. 1:N 으로 적용해야합니다. 3. 저장은 DB로 해야하는데 이때 저는 REDIS를 알게 되었습니다. 그냥 활용해보기..

codingisnoteasy.tistory.com

추가는 DTO객체를 적용시킨것 밖에는 없어요....1번글의 선배님 글에서 ....

더보기
@Repository
public class ChatRedisRepository {
    private static final Logger logger = LoggerFactory.getLogger(ChatRedisRepository.class);
    private static final String HASH_KEY = "chatData";
    private RedisTemplate<String, ChatDto> RedisTemplate;
    private HashOperations<String, String, Map<String, String> > hashOperations;

    public ChatRedisRepository(RedisTemplate<String, ChatDto> RedisTemplate) {
        this.RedisTemplate = RedisTemplate;
        this.hashOperations = RedisTemplate.opsForHash();
        }

    public void save(ChatDto chatDto) {
        String key = chatDto.getId(); //자동생성된 id 값을 사용한다.
        Map<String, String> hashData = new HashMap<>();
        hashData.put("nickName", chatDto.getNickName());
        hashData.put("message", chatDto.getMessage());
        hashData.put("roomName", chatDto.getRoomName());
        hashData.put("date", chatDto.getDate());

        hashOperations.put(HASH_KEY, key, hashData);
    }
    public ChatDto findByNickName(String nickName) {
        Map<String, String> hashData = hashOperations.get(HASH_KEY, nickName);
        logger.info("******** findByNickName hashData : {}", hashData);
        if (!hashData.equals("null") || hashData != null) {
            ChatDto cDto = ChatDto.builder().roomName(nickName).build();
            return cDto;
        }
        return null;
    }
    //모든 대화 리스트 출력
    public void findChatList() {

        Map<String, Map<String, String> > allEntries = hashOperations.entries(HASH_KEY);
        logger.info("채팅 전체 데이터 : ");
        logger.info("{}",allEntries);
        logger.info("-----------------------");

        for (Map.Entry<String, Map<String, String>> entry : allEntries.entrySet()) {
            String key = entry.getKey();
            Map<String, String> data = entry.getValue();

            System.out.println("Key: " + key);

            ChatDto chat = new ChatDto();
            chat.setNickName(data.get("nickName"));
            System.out.print("nickName : "+ chat.getNickName());
            chat.setMessage(data.get("message"));
            System.out.print(", message : "+ chat.getMessage());
            chat.setRoomName(data.get("roomName"));
            System.out.print(", roomName : "+ chat.getRoomName());
            chat.setDate(data.get("date"));
            System.out.println(", date : "+ chat.getDate());

            System.out.println("---------------------");
        }
    }

전체 조회하면 이런식으로 나옵니다. 이걸 활용해서 이것저것 할수 있는거죠..^^

추가로 채팅정보에 관련된 controller는

 @Controller
public class ChatController {
    private static final Logger logger = LoggerFactory.getLogger(ChatController.class);
    private ChatRedisRepository repo;
    private RoomRedisRepository roomRepo;
    @Autowired
    public ChatController(ChatRedisRepository repo,RoomRedisRepository roomRepo ) {
        this.repo = repo;
        this.roomRepo = roomRepo;
    }
    @Autowired
    private RedisTemplate<String, CRoomDto> redisTemplate;
 	
    @RequestMapping("/chatting")
    public ModelAndView searchRoomNum(String roomName, String password, ModelAndView mv) throws JsonProcessingException {
        try{
            CRoomDto cRoo = roomRepo.findById(roomName);

            if (cRoo.getPassWord() == null ) {
                CRoomDto cRoom = CRoomDto.builder().roomName(roomName).passWord(password).build();
                roomRepo.save(cRoom);
                mv.addObject("roomName", roomName);
                mv.setViewName("chat/chatting");
                return mv;
            } else {
                mv.addObject("roomName", roomName);
                mv.setViewName("chat/chatting");
                logger.info("all list : {}",roomRepo.findRoomAll());
                return mv;
            }
        }catch (JsonProcessingException je){
            mv.addObject("message", je.getMessage());
            mv.setViewName("index");
            return mv;
        }
    }
    }

이런거였습니다.......

제가 국비학원 졸업시 프로젝트 부분이  ajax으로 하는 채팅프로그램였습니다. 그때는 부트를 배우기 전이라서 나중에 꼭 부트 공부하고 websocket으로 해보리라 다짐했는데 업무로 어거지로 한것이 아니라 제스스로 했다는 만족감과

제가 redis도 접해봤다는것에 너무 뿌듯함을 느끼는 저만의 글입니다.^^

 

1. 웹소켓을 통해 채팅 프로그램 만들기...1에서 왠만한건 다 복붙해서 이런건 감사...

2. 1:N 으로 적용해야합니다. 

3. 저장은 DB로 해야하는데 이때 저는 REDIS를 알게 되었습니다. 그냥 활용해보기...

key, value값인데 뭘 어떻게 조회해야하나...여러 고민을 하였습니다. 첫번째 블로그만해도 금방 sysout프린트 되서
아~~~!!!너무 좋구나야 했는데 이걸 채팅룸에 비번 넣고 저장하고 불러오고 CRUD redis와 이런걸 하려니 너무 어렵더라구요. 이제부터 검색과 chatGPT(무료버전이라 오류가 좀 많아요)와의 싸움입니다... 기간은 2주였고 실제 작업한 일은 7일 정도입니다.

websocket 채팅 프로그램 코드등에 대해 정리합니다.

디자인 패턴을 꼼꼼히 맞춰서 만들지는 않았고 일단 빠른 진행을 목적으로 만들었으니깐 참고해주세요. 

1. 웹소켓을 bean으로 설정하기 위해 파일도 만들었다 어쩌구 저쩌구 많은 고생을 했는데 결론은

@SpringBootApplication
public class Chat3Application {
    /*웹소켓을 사용하기위해 설정한 Bean*/
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

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

여기다 붙이는게 가장 좋았습니다. 이유는 @serverEndpoint  때문이였습니다. 
이놈 붙은건 @기본생성자를 만들어야만 했기에 controller같은 파일은 만들어서 진행하기가 어려웠어요...왜냐??
DB저장해야하잖아요....기본로직을 따라가려니 잘 안되더라구요....3일째 여러 고생하다가 안착한 곳이...

@SpringBootApplication

붙은 Application 클래스였습니다. 에러안나는 곳은 여기 뿐이였어요.

2. 

@Configuration
public class CustomSpringConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {

    /**
     * Spring application context.
     * ServerEndpoint 는 웹소켓에 의해 세션이 연결될때마다 인스턴스가 JWA 구현에 의해 생성되고 관리되기에
	 * 생성될때마다 의존성 주입을 할수 있도록 별도 설정이 필요
     */
    private static volatile BeanFactory context;

    @Override
    public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
        return context.getBean(clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        CustomSpringConfigurator.context = applicationContext;
    }
}

redis설정....application.properties에는 기재내용은 검색해봐도 많이 넣을 필요 없이 심플심플하게..

#redis설정 == application.properties 파일에
spring.redis.host=localhost
spring.redis.port=6379

//별도로 Config 파일로 설정해주는데 
//비번 설정을 안했기에 주석처리 했구요...
//tamplate메소드는 매핑처리하는데 필요, Serializer (JSON) 처리로 추가..
@EnableRedisRepositories
@Configuration
public class RedisConfig {
    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

   /* @Value("${spring.data.redis.password}")
    private int password;
*/
   @Bean
   public RedisConnectionFactory redisConnectionFactory() {
       return new LettuceConnectionFactory(host, port);
   }

    @Bean
    public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // Key Serializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        // Value Serializer (JSON)
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

        // Hash Key Serializer
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        // Hash Value Serializer (JSON)
        redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

        return redisTemplate;

    }
        @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
    }

3. dto ..저는 채팅룸과 실제 채팅내용을 분리해서 만들었습니다.

timetoLive는 만료시간을 설정하는 속성으로 30으로 적어서 30초 후에 만료 및 조회되면 안되는데 조회됩니다.

검색결과redis폴더에서 redis.conf파일을 들어가서 maxmemory-policyvolatile-lru 또는 volatile-ttl로 설정하라고 하는데....

https://blog.naver.com/PostView.naver?blogId=whddbsml&logNo=222389726721&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView 글도 참고해보고

이렇게 조회는 되는데.....전 공부용이라서 일단 그냥 두었습니다..ㅠㅠ 사실 conf 파일까지 검색할때는 거의 끝나가는 부분이였어요. 정리를 나름 순서대로 하느라 그렇치 하면서 저는 마지막이라 이미 지쳤습니다.ㅠㅠ

그리고 왜 redis 할때 로그인 정보라던가 이런거 할때 많이 쓴다고 하더라구요. 그때 임의의 랜덤 key값이 사용되는데 그때 이건가봐요.

private String id= UUID.randomUUID().toString();

참고하세요.,

1. 프로젝트 만들어야 하잖아요...

https://jobtc.tistory.com/59 잘 만드셨더군요.......거의 복붙수준으로 했습니다...감사합니다. 선배님 꾸벅!!!

2. 저는 redis로 진행해보고 합니다.. 일단 설치...

https://learn.microsoft.com/en-us/windows/wsl/install 위에 글에도 있는데 혹시나해서...

했으나 이 후가 너무 어렵다.......영상 검색....https://www.youtube.com/watch?v=jvCC6huscOI 보세요.

Installing the Service  ------------ *--service-install*

Uninstalling the Service------------ *--service-uninstall*

Starting the Service---------------- *--service-start*

Stopping the Service---------------- *--service-stop*

Naming the Service------------------ *--service-name **name***

redis-server --service-install --service-name redisService1 --port 10001

redis-server --service-start --service-name redisService1

redis-server --service-install --service-name redisService2 --port 10002

redis-server --service-start --service-name redisService2

redis-server --service-install --service-name redisService3 --port 10003

redis-server --service-start --service-name redisService3

나가기 exit//
종료는 redis-cli.exe shutdown
종료후 재시작할때는 redis-server --service-install

http://redisgate.kr/redis/command/hashes.php

 

HASHES Introduction Redis

hashes_intro HASHES Introduction 소개 Field와 value로 구성 Hashes는 key 하나에 여러개의 field와 value로 구성됩니다. key 하나에 field와 value 쌍을 40억개(4,294,967,295)까지 저장 가능합니다. Table과 Hash의 유사한

redisgate.kr

redis와 관련된 대부분을 것을 조회 할수 있었습니다.

명령어들 일일이 검색하는것보다 훨씬 좋습니다.

1.불안함을 감추고 구글 cloud 가입해서 카드 등록 하고.(결제 맘대로 하지는 않는다고 하니깐...) 

2.적용할...프로젝트 하나만들고

3.사용자 설정하고.

4. 이클립스에  라이브러리 설치하고,

5. 환경변수 별도로 해줘야 한다.

5. gradle. build에 설정하고.

6. java class하나 만들어서 실행해보기...젠장. 2일(4시간씩)이나 걸렸다....... 말이 왜이케 어렵냐....지들은 한방에 이해할지 모르겠지만.. 난정말.아무리 내가 개발 초자라고 해도 글치 뭔말을 이렇게 어렵게 해놨는지..이미지 보여주는 것도 라이브러리 관련해서 밖에 없고. 자료 검색해도 별로 안나오고 구글 나뻐.!!!!!!!!!

일단 나중에 또 구글 api를 써야 하기때문에 정리 하는 것임으로 부족해도 참고하시길....

 

1. 회원가입하니깐 자동을 화면이 뜹니다...예시 이미지도 필요없어요....돈받아야 하니깐 알아서 화면 활성화....

구글 클라우드 플랫폼(Google Cloud Pltafrom) 계정 생성하는 방법 - LZ (lainyzine.com)  가입과정은 잘나옴.

구글 지오코딩 API 키 발급 받는 방법 (Geocoding API) - 코스모스팜 블로그 (cosmosfarm.com) 3번의 사용자 설정이 잘나옴.

 

2. .

https://cloud.google.com/translate/docs/apis?hl=ko

문서에 들어가서 가이드 내용을 참고하시는데 여기 말이 어려워요...

환경변수는 json파일로 받아서 설정해라...이거 이클립스 깔때많이 한거예요..사용자변수가서 하면되는데...

변수명 GOOGLE_APPLICATION_CREDENTIALS으로 넣어주고 파일주소 복붙해주고...

 

4.라이브 러리 에서 좀 해맸는데...그냥 나온데로 이클립스에서 마켓플레이스 가서 깔고 build설정해 줍니다...

그냥 build에 기재하고 import하면 안되어요 안되.....이거 받아야 해요.

implementation 'com.google.cloud:google-cloud-translate:2.16.0'

그이후에 실행했던...계속 에러...에러...나 사용자 계정 나 했는데 계속 에러...

에러 메세지io.grpc.StatusRuntimeException: PERMISSION_DENIED: Cloud IAM permission 'cloudtranslate.generalModels.predict' denied. 계속 발생

봤더니 가이드 문서에서 가져온 코드가  나하고 안맞는거였다..ㅠㅠ

import com.google.cloud.translate.Translate;
import com.google.cloud.translate.TranslateOptions;
import com.google.cloud.translate.Translation;

public class TranslateText {
  public static void main(String... args) throws Exception {
    // Instantiates a client
    Translate translate = TranslateOptions.getDefaultInstance().getService();

    // The text to translate
    String text = "Hello, world!";

    // Translates some text into Russian
    Translation translation =
        translate.translate(text, Translate.TranslateOption.targetLanguage("ru"));

    System.out.printf("Text: %s%n", text);
    System.out.printf("Translation: %s%n", translation.getTranslatedText());
  }
}

그랬더니..나왔다..ㅋㅋㅋㅋㅋㅋㅋ드뎌.사용.

막상 다 해놓으면 별거 없는데....하는데까지 오랜시간이 걸린다..ㅠㅠㅠ

MariaDB Products & Tools Downloads | MariaDB

 

MariaDB Downloads: Free open source database & tools | MariaDB

Download MariaDB products, tools and connectors. Get the latest versions of MariaDB Community Server, MaxScale, and free trials of SkySQL and Xpand.

mariadb.com

 업무상 필요해서 한번 설치 해봅니다~

버전은 10.9.6  이고 다운로드 후 인스톨까지 마친다음...cmd창에서 여부 확인입니다.

mysql.exe -u root -p 입력하고 엔터하면 비번....비번 입력후 엔터하면...쭈루룩 나옵니다.

CREATE DATABASE Investar;  Investar란 DB생성하고

SHOW DATABASES; Investar에 아무것도 없음을 확인.

use investar; investar db를 쓰겠다~~~~

 show tables; 테이블 보자~~~~

drop database investar; db삭제

select version(); 버전확인. 이렇게 하고.....이클립스에서 db연결하면됩니다.

 

build.gradle엔

//DB연결

implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '10.9.6'

 

~application.java파일에는

spring.datasource.hikari.driver-class-name=org.mariadb.jdbc.Driver

spring.datasource.hikari.jdbc-url=jdbc:mariadb://localhost:3306/(DB이름)?characterEncoding=UTF-8&serverTimezone=UTC

spring.datasource.hikari.username=사용자이름을 넣으세요...

spring.datasource.hikari.password=비번넣으셔요.

이랬던.......web.xml이 생기면서 에러가 납니다.....그럼 

 

이클립스 스프링부트 혼자하기 2- 재설치...mysql과의 씨름 :: 미치게힘든코딩 (tistory.com)

 

이클립스 스프링부트 혼자하기 2- 재설치...mysql과의 씨름

사실 db설치부터 굉장히 고생했다.. 오라클.....회사서 설치하니 방화벽 머시기 땜시 2일을 죽도로 삭제 - 재설치 - 삭제 재설치.......무한반복했는데 선배님 왈 """설정부터 안되는건 안되는건여요

codingisnoteasy.tistory.com

마지막꺼 보세요......뻘짓도 다~~~역사가 됩니다.

 

////////////////////////////////////////////////////////////////////////////////////////////////

새벽 2시 22분입니다....

드디어 마리아 db연결해서 스프링 부트가 완성되었습니다....

1차 에러 났는데...

implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '10.9.6' 빌드가 잘못되었어요......

마리아DB는 db와 연결하는 Connector/J 가 별도로 있습니다......여기서 버전은 이 Connector/J  입니다...2.7.9로 다시 기재하니깐 연결이 됩니다...그럼 자동 설치....많이 해맸습니다.ㅠㅠ

2차. spring.datasource.hikari.username=root로 넣었는데.....사용자 이름이였어요...전 따로 설정했는데 깜박했습니다...ㅠㅠ

3차. 연결되었나 했더니.....Entity클래스가 없다나 뭐래나.........부트 할때 jpa관련 라이브러리 설치했는데 그것 때문인가 싶어....dependency삭제했더니 됩니다...이건 눈치껏 금방 알았습니다... 

드뎌 부트가 실행되었습니다. 마리아 db  까지만 연결하고 오늘은 요만...ㅠㅠ

'SPRING' 카테고리의 다른 글

springboot, webSocket, Redis. chat --1 설치  (1) 2023.06.09
구글 translation api 사용해보기.  (1) 2023.05.20
LOG를 대체하는 logger  (0) 2022.11.10
JUNIT TEST 2-controller//  (0) 2022.11.10
LOG4j 등록  (0) 2022.10.11

수업진행 하면서 앞서 log4배웠으나 안쓸때......

system.out.println을 대체할수 있는것을 한개더 알려주셨다.

public class MemberControllerTest {
	
	//org.slf4j.Logger 이걸로 해야한다.
	private static final Logger logger=LoggerFactory.getLogger(MemberControllerTest.class);
	@Autowired
	private WebApplicationContext wac;   //context ==객체에 대한 정보가 들어가 있다. 테스트를 위한 준비 객체

	private MockMvc mockMvc;
	
	@Before //JUINT껄로 임포트
	public void setup() {
		//mockMvc 사용하기 위해 builder와 wac객체를 이용하여 setup!
		this.mockMvc=MockMvcBuilders.webAppContextSetup(this.wac).build();
		logger.info("setup() 완료!!!");
	}
	@Test
	public void testMemberRegister() throws Exception{
		try {
			//mockMuc.perform(post(url)) ...perform 어떤 메소드,,, 어떤 url인가를 지정하는 것
			mockMvc.perform(post("/memberRegister.do")
					.param("userId","khadmin")
					.param("passwd","qwer1234")
					.param("name","김경호")
					.param("email","khadmin.com")
					.param("tel","01099998888"))
			.andDo(print())  //andDo 결과 확인을 위해...print 콘솔에 출력
			.andExpect(status().isOk());  //성공 할꺼를 예상하고 결과값중에 출력란것..		
			logger.info(">>>테스트 성공<<<");		
		} catch (Exception e) {
			logger.info(">>>테스트 실패<<<"+e.getMessage());	
		}
	}
	

}
MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /memberRegister.do
       Parameters = {userId=[khadmin], passwd=[qwer1234], name=[김경호], email=[khadmin.com], tel=[01099998888]}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.kh.junspring.member.controller.MemberController
           Method = public org.springframework.web.servlet.ModelAndView com.kh.junspring.member.controller.MemberController.memberRegister(org.springframework.web.servlet.ModelAndView,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = common/errorPage
             View = null
        Attribute = modelAndView
            value = ModelAndView [view="common/errorPage"; model={msg=회원가입 성공!}]
           errors = []
        Attribute = msg
            value = 회원가입 성공!

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Language:"en"]
     Content type = null
             Body = 
    Forwarded URL = /WEB-INF/views/common/errorPage.jsp
   Redirected URL = null
          Cookies = []
INFO : com.kh.junspring.member.MemberControllerTest - >>>테스트 성공<<<

이렇게 결과나 나온다.....INFO>>>>>

앞서서 배운건 자동으로 다 나오니깐 그냥 그걸 쓸것이다.^^ 

확인해야할 메소드마다 한줄씩 넣어줬다가 지워줘야 하는데 귀찮다.^^

'SPRING' 카테고리의 다른 글

구글 translation api 사용해보기.  (1) 2023.05.20
이클립스 부트 mariaDB설치 ...에러백만돌이  (0) 2023.05.19
JUNIT TEST 2-controller//  (0) 2022.11.10
LOG4j 등록  (0) 2022.10.11
AOP를 이용한 트랜젝션  (0) 2022.10.11

이제 controller도 잘  작동되는지 테스트......

앞선 과정은 이미 했고.......test 폴더에 한개 더 만든다.

 

 

이땐 controllerTest 클래스는 그냥 클래스 파일이다. 어차피 다 그냥 타이밍 해서 설치할게 없었다고 하셨다.

 

 

 

 

 

 

package com.kh.junspring.member;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
//Controller 및 웹환경에서 사용되는 빈을 자동 생성 등록
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"file:src/main/webapp/WEB-INF/spring/root-context.xml"
		, "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
public class MemberControllerTest {
	
	@Autowired
	private WebApplicationContext wac;   //context ==객체에 대한 정보가 들어가 있다. 테스트를 위한 준비 객체

	private MockMvc mockMvc;
	
	@Before //JUINT껄로 임포트
	public void setup() {
		//mockMvc 사용하기 위해 builder와 wac객체를 이용하여 setup!
		this.mockMvc=MockMvcBuilders.webAppContextSetup(this.wac).build();
	}
	@Test
	public void testMemberRegister() throws Exception{
		try {
			//mockMuc.perform(post(url)) ...perform 어떤 메소드,,, 어떤 url인가를 지정하는 것
			mockMvc.perform(post("/memberRegister.do")
					.param("userId","khadmin")
					.param("passwd","qwer1234")
					.param("name","김경호")
					.param("email","khadmin.com")
					.param("tel","01099998888"))
			.andDo(print())  //andDo 결과 확인을 위해...print 콘솔에 출력
			.andExpect(status().isOk());  //성공 할꺼를 예상하고 결과값중에 출력란것..		
					
		} catch (Exception e) {
			
		}
	}
	

}

Mockmvc는 MVC패턴의 모조품같은것으로 TEST를 하기위한 객체라고 함...

 

이미 만들었던 memberController가 복잡해서 간단하게 한게 더 만들었다.

 

public class MemberController {
	@Autowired
	private MemberService mService;

	//text를 위한 메소드
	@RequestMapping(value="/memberRegister.do", method=RequestMethod.POST)
	public ModelAndView memberRegister(ModelAndView mv
			, @RequestParam("userId") String userId
			, @RequestParam("passwd") String passwd
			, @RequestParam("name") String name
			, @RequestParam("email") String email
			, @RequestParam("tel") String tel) {
		Map<String, String> paramMap =  new HashMap<String, String>();
		paramMap.put("userId", userId);
		paramMap.put("passwd", passwd);
		paramMap.put("name", name);
		paramMap.put("email", email);
		paramMap.put("tel", tel);
		
		int result = mService.registerMember(paramMap);
		String str="";
		if(result > 0) {
			str="회원가입 성공!";
		}else {
			str="회원가입 실패!";
		}
		mv.addObject("msg", str);
		mv.setViewName("common/errorPage");
		return mv;
	}

같은 메소드에 멤버변수를 변경해서 진행.......가능하게 만드는 건 오버로드....(복습)^^

db까지 가지는 않게 stoerLogic에서 그냥 리턴값 1로 만들어서 진행됨.

결과내용은 콘솔에 띄어줌.

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /memberRegister.do
       Parameters = {userId=[khadmin], passwd=[qwer1234], name=[김경호], email=[khadmin.com], tel=[01099998888]}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.kh.junspring.member.controller.MemberController
           Method = public org.springframework.web.servlet.ModelAndView com.kh.junspring.member.controller.MemberController.memberRegister(org.springframework.web.servlet.ModelAndView,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = common/errorPage
             View = null
        Attribute = modelAndView
            value = ModelAndView [view="common/errorPage"; model={msg=회원가입 성공!}]
           errors = []
        Attribute = msg
            value = 회원가입 성공!

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Language:"en"]
     Content type = null
             Body = 
    Forwarded URL = /WEB-INF/views/common/errorPage.jsp
   Redirected URL = null
          Cookies = []

일단 잘 출력된다.. 감사하다^^

'SPRING' 카테고리의 다른 글

이클립스 부트 mariaDB설치 ...에러백만돌이  (0) 2023.05.19
LOG를 대체하는 logger  (0) 2022.11.10
LOG4j 등록  (0) 2022.10.11
AOP를 이용한 트랜젝션  (0) 2022.10.11
예외처리 어노테이션  (0) 2022.10.07

Logging 이란 :  오류에 대해 디버깅 하거나 프로그램 상태를 모니터링 하기위해 필요한 정보를 기록하는 것/ 실행->추적-> 기록(콘솔, 파일, 데이터베이스) 메세지를 작성하는 것

 

설정//pom.xml

	<dependency>
	<groupId>org.bgee.log4jdbc-log4j2</groupId>
	<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
	<version>1.16</version>
	</dependency>

설정2 : root-context.xml

	<!-- Root Context: defines shared resources visible to all other web components -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"> </property>  <!--set메소드 사용시 적었던것   -->
		<property name="url"  			 value="jdbc:oracle:thin:@localhost:1521:xe"></property>
		<property name="username" 		 value="STRING"></property>
		<property name="password" 		 value="STRING"></property>
	</bean>

이랫던 내용을

<!-- Root Context: defines shared resources visible to all other web components -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"> </property>  <!--set메소드 사용시 적었던것   -->
		<property name="url"  			 value="jdbc:log4jdbc:oracle:thin:@localhost:1521:xe"></property>
		<property name="username" 		 value="STRING"></property>
		<property name="password" 		 value="STRING"></property>
	</bean>

변경한다.  ///위에 오라클 빼먹고 갭쳐했다...아래 보면 value값에 oracle 정상 기재되어 있다 주의!!!221109 다시해보려고 했더니.....DB접속이 안되서 봤더니. 저런실수가 있었다........주의!!!!!

 

설정3 : log4파일들

log4jdbc.log4j2.properties파일을 만들고 파일안에

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

붙여 넣는다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<logger name="com.kh.junspring">
		<level value="info" />
	</logger>
	
<!-- 	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>
 	
	<!-- SQL Logger part2 -->
	<!--열려 있는 연결 수립 및 해제 이벤트를 기록, 연결문제를 찾아내는데 유요함  -->
	<logger name="jdbc.connection" additivity="false">
		<level value="warn"></level>
		<appender-ref fer="console"></appender-ref>
	</logger>
	
	<!--SQL문고 해당 SQL을 실행시키는 수행된 시간 정보를 포함  -->
	<logger name="jdbc.sqltiming" additivity="false">
		<level value="debug" />
		<appender-ref ref="console" />
	</logger>

	<!--SQL문만 로그를 남김, PreparedStatement일 경우 ?(위치 홀더)값이 완전히  보임 -->
	<logger name="jdbc.sqlonly" additivity="false">
		<level value="warn" />  
		<!-- debug(info_debug까지 다 보임)로 하면 너무 많이 조회됨  warn으로 변경-->
		<appender-ref ref="console" />
	</logger>

	<!--debug였으나 info로 변경  -->
	<logger name="jdbc.audit" additivity="false">
		<level value="info" />
		<appender-ref ref="console" />
	</logger>
	
	<!--ResultSet을 제외한 모든 JDBC호출 정보를 로그로 남김, 로그양이 많고 필요하지 않으면 사용 권장안함  debug였으나 warn로 변경 -->
	<logger name="jdbc.resultset" additivity="false">
		<level value="warn" />
		<appender-ref ref="console" />
	</logger>
	
	<!--SQL결과 조회된 데이터의 table를 그려줌 / debug였으나 info로 변경 -->
	<logger name="jdbc.resultsettable" additivity="false">
		<level value="info" />
		<appender-ref ref="console" />
	</logger>


	<!-- Root Logger -->
	<root>
		<priority value="warn" />
		<appender-ref ref="console" />
	</root>
	
</log4j:configuration>

log4j.xml파일을 수정한다.

오타나면 당근 안됨/ 서버 수정했기때문에 오타나면 연결안됨

저장 후 게시판을 실행시켜 보면

잘된건지 안된건지 모르겠다.....일단 테이블이 나오니깐 된것같기도^^

수정시에는 value값을 변경해주기....난error로 할까나??

'SPRING' 카테고리의 다른 글

LOG를 대체하는 logger  (0) 2022.11.10
JUNIT TEST 2-controller//  (0) 2022.11.10
AOP를 이용한 트랜젝션  (0) 2022.10.11
예외처리 어노테이션  (0) 2022.10.07
AOP 심화 : 메소드 실행시간  (0) 2022.10.07

AOP를 이용한 트랜젝션 처리:한번에 처리 해야할 업무단위.
1.JDBC : Connection 객체/conn.commti(),conn.rollback()-> Service 
2. Mybaits : :SqlSession객체/ session.commit(),session.rollback() ->Service
3. Sprig : TransactionManager / 객체

 

사용위한 설정 : root-context.xml

http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd "

붙인다....추가추가

사용할때 가장 중요한 것이 이부분이다. 여기가 정상기재시 일을 할수 있다...

 

이제 매니저 등록

<!-- 내가 트랜잭션 매니저다 선언 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<!-- 트랜재션 XML방식-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--매니저가 누구다. -->
		<!-- 하단의 메소드에서 작동해야한다.  -->
		<tx:attributes> 
			<tx:method name="print*" read-only="true"/>
			<tx:method name="register*" rollback-for="Exception"/>
			<tx:method name="modify*" rollback-for="Exception"/>
			<tx:method name="remove*" rollback-for="Exception"/>
		</tx:attributes>
	</tx:advice> 
	<!-- 매니저를 aop에 적용 -->
	<aop:config proxy-target-class="true">
		<aop:pointcut expression="execution(* com.kh.junspring..*Impl.*(..))" id="serviceMethod"/>
		<!--com.kh.junspring패키지의 하위 클래스까지포함해 Impl로 끝나는 클래스의 모든매변변수 메소드에 적용  -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
	</aop:config>
	</beans>

일부러 회원가입할때 한번 더 되도록 에러구문을 만들었다...

오늘 회원가입 엄청했다..일부러 에러 발생시켜 봤는데 에러메세지가 나와도 ROOT파일에 오타가 있다며 회원가입이 된다....그증거들..ㅋㅋㅋ

이후 오타 찾아내서 수정하니깐 에러메시지와함께 회원가입이 되지 않았다...

정리하면 앞서 잘 진행했던것도 EXCEPTION발생이 되면 자동으로 취소시켜 주는 것이다...ROLL-BACK.

'SPRING' 카테고리의 다른 글

JUNIT TEST 2-controller//  (0) 2022.11.10
LOG4j 등록  (0) 2022.10.11
예외처리 어노테이션  (0) 2022.10.07
AOP 심화 : 메소드 실행시간  (0) 2022.10.07
AOP 배우기  (0) 2022.10.07

+ Recent posts