안드로이드

 

  15강 핵심 코드 내용       

 

class LoginActivity

package kr.co.dothome.braverokmc.managerment;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

//로그인 초기 화면
public class LoginActivity extends AppCompatActivity {


    EditText idText, passwordText;
    Button loginButton;

    TextView registerBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_main);


        idText =(EditText)findViewById(R.id.idText);
        passwordText =(EditText)findViewById(R.id.pswordText);
        registerBtn =(TextView)findViewById(R.id.registerBtn);
        loginButton=(Button)findViewById(R.id.loginButton);



        registerBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent =new Intent(LoginActivity.this, RegisterActivity.class);
                startActivity(intent);
            }
        });


        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String userID=idText.getText().toString();
                final String userPassword=passwordText.getText().toString();


                Response.Listener<String> responseListenser =new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {

                        try{

                            JSONObject jsoneRessponse=new JSONObject(response);
                            boolean succcess=jsoneRessponse.getBoolean("success");
                            if(succcess){
                                String userID= jsoneRessponse.getString("userID");
                                String userPassword=jsoneRessponse.getString("userPassword");
                                Intent intent=new Intent(LoginActivity.this, MainActivity.class);
                                intent.putExtra("userID", userID);
                                intent.putExtra("userPassword", userPassword);
                                LoginActivity.this.startActivity(intent);
                            }else{
                                AlertDialog.Builder builder=new AlertDialog.Builder(LoginActivity.this);
                                builder.setMessage("로그인에 실패하였습니다.");
                                builder.setNegativeButton("다시 시도", null);
                                builder.create();
                                builder.show();
                            }

                        }catch(Exception e){

                        }

                    }
                };

                LoginRequest loginRequest= new LoginRequest(userID, userPassword, responseListenser);
                RequestQueue queue = Volley.newRequestQueue(LoginActivity.this);
                queue.add(loginRequest);



            }
        });

    }
}









 

class LoginRequest

package kr.co.dothome.braverokmc.managerment;


import com.android.volley.Response;
import com.android.volley.toolbox.StringRequest;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by choi on 2017-05-02.
 */

public class LoginRequest extends StringRequest {

    final static private String URL="http://braverokmc2.dothome.co.kr/Login.php";

    private Map<String, String> parameters;

/*    public RegisterRequest(int method, String url,
                           Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }*/

    public LoginRequest(String userID, String userPassword,
                        Response.Listener<String> listener){

        super(Method.POST, URL, listener, null);
        try {
            //한글 깨짐 방지
          //  String st=URLEncoder.encode(userName, "UTF-8");

            parameters=new HashMap<>();
            parameters.put("userID", userID);
            parameters.put("userPassword", userPassword);

        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    @Override
    protected Map<String, String> getParams() {
        return parameters;
    }


}



 

 

         전체 코드           

 

 

 

create table `USER` (

    userID varchar(20) not null,
    userPassword  varchar(20) not null,
    userName varchar(20) not null,
    userAge int not null,
    primary key (userID)


);

create table braverokmc2.`USER` ( userID varchar(20) not null, userPassword varchar(20) not null, userName varchar(20) not null, userAge int not null, primary key (userID) ) 

insert into braverokmc2.`USER` ( userID , userPassword , userName , userAge ) values( 'hong', '1111', '홍길동' , 39) 

select * from user where userID = 'hong' and userPassword = '1111' 

 

 

 

Login.php



<?php 
//http://braverokmc2.dothome.co.kr/Login.php?userID=hong&userPassword=1111


/* mysql_connect('localhost', 'mysql_user', 'mysql_password'); */
	$con =mysql_connect("localhost", "braverokmc2", "ehtjrhks5382");
	

	/* 	3. Mysql 입출력 인코딩을 지정
	 Mysql 연동을 한다면 입출력 인코딩이 달라서가 원인이 될 수 있다고 합니다.
	아래 3줄의 소스를 추가함으로써 해결하였습니다.
	
	출처: http://jhrun.tistory.com/140 [JHRunning] */
	
	mysql_query("set session character_set_connection=utf8;");
	
	mysql_query("set session character_set_results=utf8;");
	
	mysql_query("set session character_set_client=utf8;");
	
	
	mysql_set_charset("utf8");//sql 에서 한글 깨짐
	
	if($con==true){
	//	echo "yes 연결 되었습니다.";
		
		$_POST = array_map('mysql_escape_string', $_POST);
		$_GET=array_map('mysql_escape_string', $_GET);
		
		if(isset($_GET["userID"])){
			$userID =$_GET["userID"];
			$userPassword =$_GET["userPassword"];
			
		}else if(isset($_POST["userID"])){
			$userID =$_POST["userID"];
			$userPassword =$_POST["userPassword"];
		}

		
		if(isset($userID) && isset($userPassword)){
			
				
				$stmt = "select * from braverokmc2.USER where `userID` = '$userID' and `userPassword` = '$userPassword' ";
				$rs =mysql_query($stmt, $con);
				
				if($rs === FALSE) {
					die(mysql_error()); // TODO: better error handling
				}
				
			
	/* 			
				echo "<table border='1' >";
				echo
					"<tr>
				<th>번호</th>
				<th>이름</th>
				<th>내용</th>
				<th>이메일</th>
				<th>날짜</th>
				</tr>
				"; */
					
				$response =array();
				$response["success"]=false;
				
			if($row=mysql_fetch_array($rs)){
				
				$response["success"]=true;
				$response["userID"]=$row[userID];
				$response["userPassword"]=$row[userPassword];
				$response["userName"]=$row[userName];
				$response["userAge"]=$row[userAge];
			/* 	echo "
				<tr>
				<td>$row[userID]</td>
				<td>$row[userPassword] </td>
				<td>$row[userName] </td>
				<td>$row[userAge]</td>
				<td></td>
					
				</tr>"; */
				
			}
			
			
			echo json_encode($response);

			mysql_close();
			
			
		}
		

	}else{
		//echo "no - 연결 실패 하였습습니다.";
	}
	
	

	
	


?>







 

=>샘플 출력

{
success: true,
userID: "hong",
userPassword: "1111",
userName: "홍길동",
userAge: "39"
}

 

 

 

 

 

 

 

 

 

Register.php

<?php 

/* http://braverokmc2.dothome.co.kr/Register.php?userID=q1&userPassword=1111&userName=김길&userAge=89 */

	$con =mysql_connect("localhost", "braverokmc2", "ehtjrhks5382");
	
	
/* 	3. Mysql 입출력 인코딩을 지정
	Mysql 연동을 한다면 입출력 인코딩이 달라서가 원인이 될 수 있다고 합니다.
	아래 3줄의 소스를 추가함으로써 해결하였습니다.
	
	출처: http://jhrun.tistory.com/140 [JHRunning] */
	
	mysql_query("set session character_set_connection=utf8;");
	
	mysql_query("set session character_set_results=utf8;");
	
	mysql_query("set session character_set_client=utf8;");
	
	
	
	
	
	mysql_set_charset("SET NAMES utf8");
	if($con==true){
	
		//echo "연결";

		//Injection 방어
		$_POST = array_map('mysql_escape_string', $_POST);
		$_GET=array_map('mysql_escape_string', $_GET);
		
		if(isset($_POST["userID"])){
			$userID =$_POST["userID"];
			$userPassword=$_POST["userPassword"];
			$userName=$_POST["userName"];
			$userAge=$_POST["userAge"];
			
		}else if(isset($_GET["userID"])	){
			$userID =$_GET["userID"];
			$userPassword=$_GET["userPassword"];
			$userName=$_GET["userName"];
			$userAge=$_GET["userAge"];
		}

	/* 	//한글 인코딩 확인 후 utf8 아니 면 utf8 로 변경
		$enc=mb_detect_encoding($userName, array("UTF-8", "EUC-KR", "SJIS"));
		if($userName !="UTF-8"){
			$userName=iconv($enc, "UTF-8", $userName);
		}	
		
		 *
		 *
		 */
		$stmt= "insert into braverokmc2.USER values ( '$userID', '$userPassword', '$userName' , $userAge  ) ";
		mysql_query( $stmt);
		
		
		
	/* 	mysqli_stmt_bind_param($statement, "sssi", $userID, $userPassword, $userName, $userAge);
		mysqli_stmt_execute($statement);
		 */
		$response=array();
		$response["success"] =true;
		
		//echo $userName;
		echo json_encode($response);

	}

?>



 

=>

샘플 출력

{
success: true
}

 

 

 

=>  LoginRequest 클래스 추가    

 

APP

  compile 'com.android.volley:volley:1.0.0'

 

 

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile 'com.android.volley:volley:1.0.0'
    testCompile 'junit:junit:4.12'
}

 

AndroidMainfest.xml

  <uses-permission android:name="android.permission.INTERNET"/>

 

class LoginActivity

package kr.co.dothome.braverokmc.managerment;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

//로그인 초기 화면
public class LoginActivity extends AppCompatActivity {


    EditText idText, passwordText;
    Button loginButton;

    TextView registerBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_main);


        idText =(EditText)findViewById(R.id.idText);
        passwordText =(EditText)findViewById(R.id.pswordText);
        registerBtn =(TextView)findViewById(R.id.registerBtn);
        loginButton=(Button)findViewById(R.id.loginButton);



        registerBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent =new Intent(LoginActivity.this, RegisterActivity.class);
                startActivity(intent);
            }
        });


        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String userID=idText.getText().toString();
                final String userPassword=passwordText.getText().toString();


                Response.Listener<String> responseListenser =new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {

                        try{

                            JSONObject jsoneRessponse=new JSONObject(response);
                            boolean succcess=jsoneRessponse.getBoolean("success");
                            if(succcess){
                                String userID= jsoneRessponse.getString("userID");
                                String userPassword=jsoneRessponse.getString("userPassword");
                                Intent intent=new Intent(LoginActivity.this, MainActivity.class);
                                intent.putExtra("userID", userID);
                                intent.putExtra("userPassword", userPassword);
                                LoginActivity.this.startActivity(intent);
                            }else{
                                AlertDialog.Builder builder=new AlertDialog.Builder(LoginActivity.this);
                                builder.setMessage("로그인에 실패하였습니다.");
                                builder.setNegativeButton("다시 시도", null);
                                builder.create();
                                builder.show();
                            }

                        }catch(Exception e){

                        }

                    }
                };

                LoginRequest loginRequest= new LoginRequest(userID, userPassword, responseListenser);
                RequestQueue queue = Volley.newRequestQueue(LoginActivity.this);
                queue.add(loginRequest);



            }
        });

    }
}









 

class LoginRequest  =>추가된 클래스

package kr.co.dothome.braverokmc.managerment;


import com.android.volley.Response;
import com.android.volley.toolbox.StringRequest;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by choi on 2017-05-02.
 */

public class LoginRequest extends StringRequest {

    final static private String URL="http://braverokmc2.dothome.co.kr/Login.php";

    private Map<String, String> parameters;

/*    public RegisterRequest(int method, String url,
                           Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }*/

    public LoginRequest(String userID, String userPassword,
                        Response.Listener<String> listener){

        super(Method.POST, URL, listener, null);
        try {
            //한글 깨짐 방지
          //  String st=URLEncoder.encode(userName, "UTF-8");

            parameters=new HashMap<>();
            parameters.put("userID", userID);
            parameters.put("userPassword", userPassword);

        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    @Override
    protected Map<String, String> getParams() {
        return parameters;
    }


}



 

 

 

 

class MainActivity

package kr.co.dothome.braverokmc.managerment;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;


//로그인 성공시
public class MainActivity extends AppCompatActivity {


    TextView idText, pswordText, welcome;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        idText =(TextView)findViewById(R.id.idText);
        pswordText =(TextView)findViewById(R.id.pswordText);
        welcome=(TextView)findViewById(R.id.welcome);

    }
}

 

class RegisterActivity

package kr.co.dothome.braverokmc.managerment;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.InputFilter;
import android.text.Spanned;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

import java.util.regex.Pattern;

public class RegisterActivity extends AppCompatActivity {

    EditText idText, pswordText, nameText, ageText;
    Button registerButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);

        idText =(EditText)findViewById(R.id.idText);
        pswordText =(EditText)findViewById(R.id.pswordText);
        nameText =(EditText)findViewById(R.id.nameText);
        ageText =(EditText)findViewById(R.id.ageText);

        idText.setFilters(new InputFilter[] {filter});



        registerButton=(Button)findViewById(R.id.registerbutton);

        registerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String userID=idText.getText().toString();
                String userPassword=pswordText.getText().toString();
                String userName=nameText.getText().toString();
                int userAge=Integer.parseInt(ageText.getText().toString());

                Response.Listener<String> responseListener=new Response.Listener<String>(){

                    @Override
                    public void onResponse(String response) {
                        try{
                            JSONObject jsonResponse=new JSONObject(response);
                            boolean success=jsonResponse.getBoolean("success");

                            if(success){
                                AlertDialog.Builder builder=new AlertDialog.Builder(RegisterActivity.this);
                                builder.setMessage("회원 등록에 성공했습니다.")
                                        .setPositiveButton("확인", new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                Intent intent=new Intent(RegisterActivity.this, LoginActivity.class);
                                                RegisterActivity.this.startActivity(intent);
                                            }
                                        })
                                        .create()
                                        .show();

                            }else{
                                AlertDialog.Builder builder=new AlertDialog.Builder(RegisterActivity.this);
                                builder.setMessage("회원 등록에 실패했습니다.")
                                        .setNegativeButton("다시 시도", new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                Intent intent=new Intent(RegisterActivity.this, RegisterActivity.class);
                                                RegisterActivity.this.startActivity(intent);
                                            }
                                        })
                                        .create()
                                        .show();
                            }

                        }catch (Exception e){
                            e.printStackTrace();
                        }

                    }
                };

                RegisterRequest registerRequest=new RegisterRequest(userID, userPassword,
                        userName,userAge, responseListener);
                RequestQueue queue = Volley.newRequestQueue(RegisterActivity.this);

                queue.add(registerRequest);
            }
        });
    }


    // 영문만 허용 (숫자 포함)

    protected InputFilter filter= new InputFilter() {

        public CharSequence filter(CharSequence source, int start, int end,

                                   Spanned dest, int dstart, int dend) {



            Pattern ps = Pattern.compile("^[a-zA-Z0-9]+$");

            if (!ps.matcher(source).matches()) {

                return "";

            }

            return null;

        }

    };

    // 한글만 허용
    public InputFilter filterKor = new InputFilter() {

        @Override
        public CharSequence filter(CharSequence source, int start, int end,

                                   Spanned dest, int dstart, int dend) {



            Pattern ps = Pattern.compile("^[ㄱ-가-힣]+$");

            if (!ps.matcher(source).matches()) {

                return "";

            }

            return null;

        }

    };






}

 

 

class RegisterRequest

package kr.co.dothome.braverokmc.managerment;


import com.android.volley.Response;
import com.android.volley.toolbox.StringRequest;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by choi on 2017-05-02.
 */

public class RegisterRequest extends StringRequest {

    final static private String URL="http://braverokmc2.dothome.co.kr/Register.php";

    private Map<String, String> parameters;

/*    public RegisterRequest(int method, String url,
                           Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }*/

    public RegisterRequest(String userID, String userPassword, String userName, int userAge,
                           Response.Listener<String> listener){

        super(Method.POST, URL, listener, null);
        try {
            //한글 깨짐 방지
          //  String st=URLEncoder.encode(userName, "UTF-8");

            parameters=new HashMap<>();
            parameters.put("userID", userID);
            parameters.put("userPassword", userPassword);
            parameters.put("userName", userName);
            parameters.put("userAge", userAge +"");


        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    @Override
    protected Map<String, String> getParams() {
        return parameters;
    }


}



 

 

R.layout.activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="kr.co.dothome.braverokmc.managerment.MainActivity">

    <TextView
        android:id="@+id/welcome"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        />

    <TextView
        android:id="@+id/idTextText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="아이디"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline" />

    <TextView
        android:id="@+id/idText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />


    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="비밀번호"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline" />

    <TextView
        android:id="@+id/pswordText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />


</LinearLayout>

 

R.layout.activity_register

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="kr.co.dothome.braverokmc.managerment.RegisterActivity">

    <EditText
        android:id="@+id/idText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:ems="10"
        android:hint="아이디"
        android:inputType="" />

    <EditText
        android:id="@+id/pswordText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="비밀번호"
        android:inputType="textPassword" />

    <EditText
        android:id="@+id/nameText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="18dp"
        android:ems="10"
        android:hint="이름"
        android:inputType="textPersonName" />

    <EditText
        android:id="@+id/ageText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="나이"
        android:inputType="number" />

    <Button
        android:id="@+id/registerbutton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"
        android:text="회원가입" />



</LinearLayout>

 

 

 

R.layout.login_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="kr.co.dothome.braverokmc.managerment.LoginActivity">

    <EditText
        android:id="@+id/idText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:ems="10"
        android:hint="아이디"
        android:inputType="textPersonName" />

    <EditText
        android:id="@+id/pswordText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/idText"
        android:ems="10"
        android:hint="비밀번호"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/loginButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/text1"
        android:layout_marginTop="86dp"
        android:text="로그인" />

    <TextView
        android:id="@+id/registerBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/loginButton"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp"
        android:text="회원가입"
        android:textAppearance="@style/TextAppearance.AppCompat" />
</RelativeLayout>

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  머나먼나라

육체의 노예가 되는 사람이 어찌 자유를 누릴 수 있을까? -세네카

댓글 ( 0)

댓글 남기기

작성