일시 : 2022-02-05
범위 : 자바 웹 프로그래밍 Next Step 9장 실습(p306-p331)
목적 : 지금까지 학습한 내용을 최종 점검
실습 : https://github.com/jeonye/jwp-basic/tree/paractice-step7-self-check
문제1, 2를 풀었던 2022-01-31 Study에 이어서 학습
WebServerLauncher를 실행시키면 톰캣이 구동된다.
톰캣이 구동된 후 http://localhost:8080/ URL을 실행하면 아래와 같은 Exception이 발생한다.
The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
✳︎ 구글링을 해보니 $TOMCAT_HOME$/lib 에 jstl1.2.jar 파일을 추가 하면된다고 한다.
하지만, WebServerLauncher를 통해서가 아닌 Tomcat을 직접 구동시키면 정상적으로 질문 목록이 표시된다. 무슨 차이일까?
AddQuestionController에서 return할 때, 저장한 질문 데이터를 함께 return 했는가?
'/'로 이동할 경우 HomeController에서 질문 목록을 재조회하기 때문에 나는 넘기지 않았다.
return jspView("/");
A) Object 넘기지 않고, '/'로 리다이렉트
글쓴이와 로그인 사용자가 같은 경우에만 질문 수정이 가능해야한다.
질문의 writer에는 사용자ID가 아닌 사용자명이 저장되기 때문에, 사용자명으로 수정 가능 여부를 체크해야하는데 동명이인인 경우에는 어떻게하지?
A) 방법3으로 대응
ShowController는 멀티스레드 상황에서 문제가 발생할 수 있다.
멀티스레드 상황에서 문제가 발생하지 않도록 수정하고, 문제가 되는 이유를 설명하라.
public class ShowController extends AbstractController {
private Question question;
private List<Answer> answers;
}
이를 해결하기 위해서는 스레드별로 인스턴스를 생성하도록 전역변수로 선언된 Model 객체를 지역변수로 변경해야한다.
▶︎ 수정 전
public class ShowController extends AbstractController {
private QuestionDao questionDao = new QuestionDao();
private AnswerDao answerDao = new AnswerDao();
private Question question;
private List<Answer> answers;
@Override
public ModelAndView execute(HttpServletRequest req, HttpServletResponse response) throws Exception {
...
}
}
▶︎ 수정 후
public class ShowController extends AbstractController {
private QuestionDao questionDao = new QuestionDao();
private AnswerDao answerDao = new AnswerDao();
@Override
public ModelAndView execute(HttpServletRequest req, HttpServletResponse response) throws Exception {
...
Question question = questionDao.findById(questionId);
List<Answer> answers = answerDao.findAllByQuestionId(questionId);
...
}
}
별도 게시글에 책 내용을 옮겨놓았으니 별도 게시글에서 확인한다.
자바 기반으로 웹 프로그래밍을 할 경우 한글이 깨진다. 이러한 문제는 ServletFilter를 활용해 해결할 수 있다.
web.xml을 통해 서블릿, 필터 설정을 해야하지만, 서블릿 3.0부터는 자바 소스상에서 대체할 수 있는 @WebFilter 어노테이션이 추가되었다.
@WebFilter 어노테이션을 통해 특정 url패턴에 매핑되는 필터를 설정할 수 있으며, 만약 필터 초기화시에 설정할 파라미터를 지정하고 싶은 경우에는 initParams 속성에 @WebInitParam 어노테이션을 사용하여 속성명과 속성값을 지정해주면 된다.
@WebFilter(
value= {"/*"},
initParams=@WebInitParam(name="encoding", value="utf-8")
)
<참고>
아래와 같이 웹 브라우저에서 접속했는지, 모바일에서 접속했는지 확인할 수 있다.
private static final String IS_MOBILE = "MOBI";
private static final String IS_PC = "PC";
public static String isDevice(HttpServletRequest req) {
String userAgent = req.getHeader("User-Agent").toUpperCase();
if(userAgent.indexOf(IS_MOBILE) > -1) {
return IS_MOBILE;
} else {
return IS_PC;
}
}
11번 문제는 글쓴이와 로그인 사용자가 같은 경우에만 질문 수정이 가능하도록 구현하는 것이었다.
자신의 글인 경우에만 화면에서 수정/삭제 버튼이 보이고, 다른 사람의 글에는 수정/삭제 버튼이 보이지 않도록 구현했다.
이렇게 클라이언트 화면 구현만으로 구현을 완료한 경우, 해커는 브라우저가 아닌 다른 HTTP 클라이언트나 브라우저 플러그인을 통해 웹 서버에 요청을 보내 다른 사람의 글을 수정하고 삭제할 수 있다.
따라서, 서버측에서도 처리할 수 있도록 고려해야한다.
추가로 서버측 처리 중 로그인 사용자를 조회할 때, 쿠키를 통해 사용자 정보를 얻는 것 보다는 가능하면 세션에서 사용자 정보를 조회하는 것이 좋다.