2022년 7월 28일 목요일

apache2 HTTP2 설정

 # http2 모듈 사용

a2enmod http2


# conf 파일 수정

Protocols h2 h2c http/1.1


# 테스트

curl -I --http2 -s https://domain.com/ | grep HTTP


# 테스트 결과















자료 출처: https://httpd.apache.org/docs/2.4/mod/mod_http2.html




2022년 7월 26일 화요일

apache2 웹서버 인증(basic authentication)

로컬 또는 내부 특정 웹서버 로그인 기능 추가하기.

예제는 Basic 인증으로 작성 됨.


# 대략적인 흐름

도메인 접속 > apache basic 인증 > 프록시 > 내부 웹서버 


# 설치
sudo apt install apache2-utils


# 계정추가
htpasswd -c /etc/apache2/.htpasswd test


# VirtualHost 설정, 프록시 패스

<VirtualHost *:80>

        ServerName 도메인

        ServerSignature Off

        RewriteEngine on

        RewriteCond %{HTTPS} !=on

        RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [NE,R,L]

</VirtualHost>

<VirtualHost *:443>

        ServerName 도메인

        ServerSignature Off

        ProxyPreserveHost On

        AllowEncodedSlashes NoDecode

        RequestHeader set X_FORWARDED_PROTO 'https'

        RequestHeader set X-Forwarded-Ssl on

        ProxyPass / http://127.0.0.1:10012/

        ProxyPassReverse / http://127.0.0.1:10012/

        <Proxy *>

                Order deny,allow

                Allow from all

                Authtype Basic

                Authname "Password Required"

                AuthUserFile /etc/apache2/.htpasswd

                Require valid-user

        </Proxy>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>



# 테스트 결과

sudo service apache2 restart




ubuntu 웹캠 연동 메모

 # ubuntu 웹캠 연결 확인 방법

sudo apt install v4l-utils


# 카메라 번호 확인

ls -ltrh /dev/video*


# 포멧 체크

sudo v4l2-ctl -d /dev/video0 --list-formats-ext

sudo v4l2-ctl -d /dev/video1 --list-formats-ext


# 그룹권한 확인 및 추가

sudo groups 계정명

gpasswd -a 계정명 video

sudo usermod -a -G video 계정명


여기까지 설정이 완료되면 웹캠을 사용할 수 있음

만약 안된다면 재부팅 후 다시 확인.


# 테스트 환경

ubuntu 22.04 LTS

앱코 QHD 웹캠 APC930




2022년 7월 21일 목요일

MariaDB 초기 설정 메모

# 설치

apt install mariadb-server



# 설정
ubuntu 기준으로 작성.

- 포트변경 방법
vi /etc/mysql/my.cnf
port = 1234

- 접속IP 변경, 타임존 변경
vi /etc/mysql/mariadb.conf.d/50-server.cnf
bind-address            = 0.0.0.0 
default-time-zone       = '+9:00'

- 설정변경 확인
service mariadb restart
netstat -nl | grep 1234

- 초기화 설정 진행
mysql_secure_installation



# 초기설정 SQL
- 접속
mysql -u root -p

- DB 목록 조회
show databases;
- 계정 조회
select host, user, password from mysql.user;
- DB 생성
create database testdb;
- 계정생성
create user 'testuser'@'%' identified by 'qwer1234';
- 패스워드 변경
UPDATE user SET password = password('원하는비밀번호') WHERE user = 'testuser';
- 권한 부여
grant all privileges on testdb.* to 'testuser'@'%';
flush privileges;
- 전역 인코딩 확인
show variables like "%char%";
- 데이터베이스 인코딩 확인
SELECT default_character_set_name, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA  WHERE schema_name = "testdb";
- 타임존 확인
SELECT @@GLOBAL.time_zone, @@SESSION.time_zone, @@system_time_zone;

2022년 7월 19일 화요일

clamav 설치 및 기본 사용방법

개발계 환경에서 딱히 필요할 것 같지는 않지만 혹시 모르니 메모..



# 설치

apt install clamav

apt install clamav-daemon


# 바이러스 체크

clamscan -r 체크경로 --move=이동경로

move에 설정된 경로에 감염된 파일이 이동 됨


# 바이러스 DB 수동 업데이트 방법

service clamav-freshclam stop

freshclam

service clamav-freshclam start



2022년 7월 18일 월요일

리눅스 로그인 배너 꾸미기

 # Banner 설정

vi /etc/ssh/sshd_config


Banner /etc/issue.net

Banner /etc/issue

Banner /etc/motd


issue.net - 원격접속 배너

issue - 로컬 접속 배너

motd - 로그인 후 배너


# 적용

service sshd restart


배너는 아스키 아트를 사용하여 이쁘게 꾸미면 됩니다.

https://www.asciiart.eu/


적용 예)



ubuntu samba 설치

 # samba 설치

apt install samba


# 설정 변경

vi /etc/samba/smb.conf

[homes]

   comment = Home Directories

   valid users = %S

   browseable = no

   read only = no

   guest ok = no

   writable = yes

   create mask = 0644

   directory mask = 0755

   

# 설정 적용

service smbd restart


# 계정 추가

smbpasswd -a test


# 윈도우 네트워크 드라이브 추가

\\192.168.0.2\test


우분투 SSH 타임아웃 설정

 vi /etc/profile


#타임아웃 지정, 120초
TMOUT=120
export TMOUT

source /etc/profile

2022년 7월 17일 일요일

우분투 IP 수동 설정 방법

# 인터페이스 수정

vi /etc/netplan/00-installer-config.yaml

network:

  ethernets:

    enp0s3:

      dhcp4: false

      addresses: [192.168.1.51/24]

      gateway4: 192.168.1.1

      nameservers:

        addresses: [8.8.8.8,1.1.1.1]

  version: 2


dhcp4를 false 설정하고 

아이피, 게이트웨이, DNS 설정 후 저장


# 적용

netplan apply


우분투 RTSP 재생 이슈

우분투 21.04, 우분투 22.04에서 RTSP 미디어가 재생 되지 않음...



임시 조치로 해결한 방법.

sudo apt-get install snapd
sudo snap install core
sudo snap install vlc

이 방법 말고 당장 해결할 수 있는 방법은 생각나지 않음........
피곤.

PostgreSQL 초기 설정 팁

- pg_hba.conf 

db와 db 계정의 접근제어를 설정


# postgres 계정으로 모든 db 접근, 192.168.1.x 네트워크에서만.

host    all             postgres        192.168.1.0/24       scram-sha-256

# 모든 접근 허용, 이건 위험..

host    all             all                0.0.0.0/0               scram-sha-256


- postgresql.conf

DB의 주요 설정이 이 파일에 포함되어 있음


port = 5432 # 포트번호 설정

max_connections = 100 # 최대 접속 가능 수 

log_timezone = 'Asia/Seoul' # 로그 타임존

timezone = 'Asia/Seoul' # DB 타임존

#listen_addresses = 'localhost' # 값을 *로 할 경우 모든 주소에서 접속 가능


DB에서 가장 기본적인 설정은 서버와 마찬가지로 현지시간 설정이므로

서버와 DB 모두 항상 시간을 확인할 것을 추천함.


- 초기 설정 후 자주쓰는 SQL 

# postgres 계정 패스워드 변경

alter user postgres with password 'new_password';


# DB 서버 시간 확인

select CURRENT_TIMESTAMP;


# DB 생성

CREATE DATABASE test_db

WITH OWNER postgres 

ENCODING 'UTF8'

LC_COLLATE = 'C'

LC_CTYPE = 'C'

TEMPLATE template0;




VLC 미디어 변환 예제 - RTSP, HLS, 웹캠

- RTSP를 MJPEG로 변환 방법

vlc -vvv -Idummy rtsp://localhost:558/media.smp --sout '#transcode{vcodec=MJPG,venc=ffmpeg{strict=1},fps=10,width=640,height=360}:standard{access=http{mime=multipart/x-mixed-replace;boundary=--7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8082/}'



- RTSP를 m3u8로 변환 방법

vlc -vvv -Idummy rtsp://localhost:558/media.smp --sout '#transcode{width=640,height=360,fps=10,vcodec=h264,vb=256,venc=x264{aud,profile=baseline,level=30,keyint=30,ref=1},acodec=mp3,ab=96}:std{access=livehttp{seglen=10,delsegs=true,numsegs=5,index=/var/www/html/hls/stream.m3u8,index-url=http://localhost/hls/stream-########.ts},mux=ts{use-key-frames},dst=/var/www/html/hls/stream-########.ts}'


테스트 방법.

VLC 플레이어가 있고 웹캠이 있는 PC라면 윈도우 환경 기준 dshow:// 주소를 rtsp 주소란에 넣고 테스트 가능.


테스트 예)

PC 웹캠을 브라우저에서 확인 하는 방법

vlc -vvv -Idummy dshow:// --sout #transcode{vcodec=MJPG,venc=ffmpeg{strict=1},fps=10,width=640,height=360}:standard{access=http{mime=multipart/x-mixed-replace;boundary=--7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8082/}'


테스트 URL : http://localhost:8082/


공인IP 확인 방법 - 구글 API 사용

 구글 API URL : https://domains.google.com/checkip

브라우저 주소창에 입력 후 공인IP 확인 가능


자바스크립트 또는 쉘스크립트를 통해 공인IP를 확인할 수 있음


쉘스크립트 예시)

#!/bin/sh
IP=$(curl -s https://domains.google.com/checkip )
echo $IP

리눅스의 crontab을 이용해 1시간 마다 공인IP를 확인해서 
특정 서버 위치에 저장할 경우 ddns 없이 원격접속 정보를 알 수 있음.

2020년 6월 22일 월요일

kill -15 명령어

kill -9 pid 를 사용할 경우 프로세스가 강제종료 됩니다.
현재 어떤 작업을 진행중이라면 문제가 될 수 있습니다.

가급적이면 kill -15 옵션을 사용하는 것을 권장합니다.



만약 스프링 어플리케이션이라면
application.properties에 server.shutdown=graceful 옵션을 적용하면 안전하게 종료됩니다.
(스프링부트 2.3.0 버전부터 가능한것으로 확인 됐습니다.)


자바 프로세스의 경우
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {

}
});

위 함수를 통해서 안전하게 프로세스를 종료시킬 수 있습니다.



2020년 5월 10일 일요일

Spring Boot AJP 설정

Apache의 mod_jk 구성이 필요합니다.

- Tomcat
@Configuration
public class TomcatConfiguration {

@Bean
public WebServerFactory servletContainer() {

TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
Connector ajp = new Connector("AJP/1.3");
ajp.setPort(8009);
ajp.setSecure(false);
ajp.setAllowTrace(false);
ajp.setScheme("http");
ProtocolHandler protocolHandler = ajp.getProtocolHandler();
if (protocolHandler instanceof AbstractAjpProtocol) {
AbstractAjpProtocol<?> abstractAjpProtocol = (AbstractAjpProtocol<?>) protocolHandler;
abstractAjpProtocol.setSecretRequired(false);
}
factory.addAdditionalTomcatConnectors(ajp);

return factory;
}

}


메이븐 설정은 spring-boot-starter-tomcat이 필요합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>





- Undertow
@Configuration
public class UndertowConfiguration {

@Bean
public ServletWebServerFactory servletContainer() {
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {

@Override
public void customize(Builder builder) {
builder.addAjpListener(8009, "127.0.0.1");
}
});
return factory;
}

}


메이븐 설정은 spring-boot-starter-undertow이 필요하고 undertow 구성 시 spring-boot-starter-tomcat을 제외해야 합니다.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>








2020년 3월 13일 금요일

ModSecurity MIME-TYPE 추가하기

Apache의 ModSecurity가 설정된 경우
임의의 MIME-TYPE를 설정할 때 403 에러 응답을 하는 경우를 볼 수 있습니다.

이 경우 ModSecurity 설정 파일에 다음과 같이 내용을 추가합니다.

SecAction \
 "id:900990,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.allowed_request_content_type=application/xxx|application/xxxx', \
  setvar:tx.crs_setup_version=320"

구분자는 | 문자입니다.


타입을 추가한 뒤 아파치를 재시작하고 200 OK로 처리 됩니다.



2020년 3월 12일 목요일

아파치 mod_security2 설치 - 윈도우 환경

0. 적용환경
운영체제 : Windows 10 64bit
Apache 버전 : Apache2.4
mod_security 버전 : mod_security-2.9.3-win64-VS16


1. mod_security 설치
mod_security-2.9.3-win64-VS16.zip 파일 다운로드

다운로드 : https://www.apachelounge.com/download/


- yajl.dll 설치
apache24/bin 디렉토리에 yajl.dll 복사

- mod_security2.so 설치
apache24/modules 디렉토리에 mod_security2.so 복사



2. owasp-modsecurity-crs 설치
owasp-modsecurity-crs 다운로드
owasp-modsecurity-crs-3.2.0 버전으로 설치했습니다.

다운로드 : https://github.com/SpiderLabs/owasp-modsecurity-crs

- owasp-modsecurity-crs 설정
apache24/conf 디렉토리에 owasp-modsecurity-crs 디렉토리를 만들고
압축파일 내에 있는 crs-setup.conf.example파일과 rules 디렉토리를 복사합니다.

그리고 crs-setup.conf.example 파일 이름을 crs-setup.conf로 변경합니다.



3. crs-setup.conf 설정
crs-setup.conf 파일을 열어 최상단에 다음과 같이 수정합니다.

SecRuleEngine On
SecDefaultAction "deny,phase:2,status:403"

ServerTokens Full
ServerSignature Off
SecServerSignature "TestServer"



4. httpd.conf 설정
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule security2_module modules/mod_security2.so

<IfModule security2_module> 
Include conf/owasp-modsecurity-crs/crs-setup.conf
Include conf/owasp-modsecurity-crs/rules/*.conf
</IfModule>



5. 요청 응답 해더 확인
아파치를 재시작하고
응답 헤더에 Server가 TestServer 값으로 수정된 것을 확인합니다.

http://localhost








2020년 3월 10일 화요일

우분투 - 아파치 톰캣 연동

apache2, tomcat9 연동예제입니다.


1. 설치
# apt-get install -y apache2
# service apache2 start

아파치2 접속확인
http://localhost



2. 톰캣설치
# apt-get install -y openjdk-8-jdk 
자바가 필수로 설치된 환경에서 설치합니다.

/usr/share/tomcat9경로에 설치합니다.
# cd /usr/share
# wget http://apache.mirror.cdnetworks.com/tomcat/tomcat-9/v9.0.31/bin/apache-tomcat-9.0.31.tar.gz
# tar -zxvf apache-tomcat-9.0.31.tar.gz
# mv apache-tomcat-9.0.31 tomcat9
# rm apache-tomcat-9.0.31.tar.gz
# sh /usr/share/tomcat9/bin/startup.sh

톰캣 접속확인
http://localhost:8080



3. mod-jk 설치
# apt-get install libapache2-mod-jk



4. /etc/libapache2-mod-jk/workers.properties 수정
# which java
/usr/bin/java

# readlink /usr/bin/java
/etc/alternatives/java

# readlink /etc/alternatives/java
/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java

readlink /etc/alternatives/java에서 확인된 경로와 톰캣 설치 경로를 workers.properties 파일에 설정합니다.

# vi /etc/libapache2-mod-jk/workers.properties
workers.tomcat_home=/usr/share/tomcat9
workers.java_home=/usr/lib/jvm/java-8-openjdk-amd64



5. 톰캣 server.xml 파일 수정
# vi /usr/share/tomcat9/conf/server.xml
<Connector protocol="AJP/1.3"
   port="8009"
   address="0.0.0.0"
   secretRequired="false"
   redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="ajp13_worker">

Connector의 secretRequired, address 두 설정에 오류가 있으면 연동이 안될 수 있습니다.
worker 기본 설정값인 ajp13_worker를 jvmRoute에 입력합니다.

톰캣9 재시작
# sh /usr/share/tomcat9/bin/shutdown.sh
# sh /usr/share/tomcat9/bin/startup.sh



6. /etc/apache2/sites-enabled/000-default.conf 수정
# vi /etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
        ServerName localhost
        JkMount /* ajp13_worker
        DocumentRoot /usr/share/tomcat9/webapps/ROOT
</VirtualHost>




7. /etc/apache2/apache2.conf 수정
# vi /etc/apache2/apache2.conf
ServerName localhost

서버네임이 생략된경우 추가합니다.



8. 아파치2 재시작
# service apache2 restart



9. 접속확인
http://localhost

















만약 접속이 안된다면 톰캣과 아차피 모두 재시작하고 확인합니다.
에러가 발생한다면 /var/log/apache2/ 경로에서 아파치 로그를 확인합니다.










2019년 6월 7일 금요일

안드로이드 RecyclerView 예제

- RecyclerView.ViewHolder 적용
- androidx.recyclerview.widget.DiffUtil 적용


1. RecyclerView.Adapter 구현
public class TextRecyclerAdapter extends RecyclerView.Adapter<TextRecyclerAdapter.Holder> {
    private LayoutInflater inflater;
    private final ArrayList<String> items = new ArrayList<>();

    public void updateList(final List<String> newItems) {
        TextDiff callback = new TextDiff(this.items, newItems);
        DiffUtil.DiffResult result = DiffUtil.calculateDiff(callback);
        this.items.clear();
        this.items.addAll(newItems);
        result.dispatchUpdatesTo(this);
    }

    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (inflater == null)
            inflater = LayoutInflater.from(parent.getContext());

        View itemView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
        return new Holder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position) {
        holder.bindData(getItem(position));

    }

    public String getItem(int position) {
        return items != null && position < getItemCount() ? items.get(position) : null;
    }

    @Override
    public int getItemCount() {
        return items == null ? 0 : items.size();
    }

    static class Holder extends RecyclerView.ViewHolder {
        private final TextView text;

        public Holder(@NonNull View itemView) {
            super(itemView);
            this.text = itemView.findViewById(android.R.id.text1);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Object tag = v.getTag();
                    if (tag instanceof String) {

                    }
                }
            });
        }

        public void bindData(String item) {
            itemView.setTag(item);
            if (item == null)
                return;
            text.setText(item);
        }
    }

    static class TextDiff extends DiffUtil.Callback {
        private final List<String> oldItems;
        private final List<String> newItems;

        public TextDiff(List<String> oldItems, List<String> newItems) {
            this.oldItems = oldItems;
            this.newItems = newItems;
        }

        @Override
        public int getOldListSize() {
            return oldItems.size();
        }

        @Override
        public int getNewListSize() {
            return newItems.size();
        }

        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            if (oldItemPosition > newItemPosition)
                return false;
            return oldItems.get(oldItemPosition).equals(newItems.get(oldItemPosition));
        }

        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            if (oldItemPosition > newItemPosition)
                return false;
            return oldItems.get(oldItemPosition).equals(newItems.get(oldItemPosition));
        }
    }
}


- ViewHolder 클래스를 구현해서 사용한다.
- DiffUtil 클래스를 구현해서 리스트 갱신을 효율적으로 구현한다.






2. RecyclerView 구현
public class RecyclerListFragment extends Fragment {

    public RecyclerListFragment() {
        // Required empty public constructor
    }

    public static RecyclerListFragment newInstance() {
        RecyclerListFragment fragment = new RecyclerListFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_recycler_list, container, false);
        RecyclerView recyclerView = view.findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(recyclerView.getContext());
        linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
        TextRecyclerAdapter textRecyclerAdapter = new TextRecyclerAdapter();
        recyclerView.setAdapter(textRecyclerAdapter);

        ArrayList<String> items = new ArrayList<>();
        items.add("Text Item 1");
        items.add("Text Item 2");
        items.add("Text Item 3");
        textRecyclerAdapter.updateList(items);

        return view;
    }
}


- updateList를 호출하면 DiffUtil 기능으로 리스트가 자연스럽게 갱신된다.

안드로이드 BaseAdapter 예제

- android.widget.BaseAdapter 적용
- ViewHolder 방식 사용



1. BaseAdapter 구현
public class TextListAdapter extends BaseAdapter {
    private LayoutInflater inflater;

    static class Holder {

        private final TextView text;

        public Holder(View itemView) {
            this.text = itemView.findViewById(android.R.id.text1);
        }

        void bindData(String item) {
            text.setText(item);
        }
    }

    private final ArrayList<String> contentItems = new ArrayList<>();

    @Override
    public int getCount() {
        return contentItems == null ? 0 : contentItems.size();
    }

    @Override
    public String getItem(int position) {
        return contentItems != null && position < getCount() ? contentItems.get(position) : null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (inflater == null)
            inflater = LayoutInflater.from(parent.getContext());

        Holder holder;
        if (convertView == null) {
            convertView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
            holder = new Holder(convertView);
        } else {
            holder = (Holder) convertView.getTag();
        }

        holder.bindData(getItem(position));
        return convertView;
    }
}

- Holder 클래스(ViewHolder)를 View 태그에 넣어서 재활용한다.
- ListView 어뎁터 구현의 가장 기본이 되는 방식.




2. ListView 구현
public class TextListFragment extends Fragment {

    public TextListFragment() {
        // Required empty public constructor
    }

    public static TextListFragment newInstance() {
        TextListFragment fragment = new TextListFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ArrayList<String> items = new ArrayList<>();
        items.add("Text Item 1");
        items.add("Text Item 2");
        items.add("Text Item 3");

        View view = inflater.inflate(R.layout.fragment_text_list, container, false);
        ListView listView = view.findViewById(R.id.listView);
        listView.setAdapter(new TextListAdapter(items));
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Object item = parent.getItemAtPosition(position);
                if (item instanceof String) {

                }
            }
        });
        return view;
    }
}


- AdapterView에서 아이템을 가져와 클릭이벤트에 해당하는 아이템을 불러온다.