728x90
300x250

[이야기] JSP/Servlet의 RestEasy 4.8(Jboss)로 Rest 실험 이야기(한글 미지원)


결론부터 이야기하면, REST 구현에는 성공했다. 하지만, 문제는 한글 문제인데, 인코딩 관련해서 많은 실험을 하였으나 동작하지 않았다.

삽질하려고 하는 사람이 있다면, 정리하는 걸 추천한다.


REST가 쉽사리 활성화되지 않은 이유도 있을 거 같다. 

C#이나 PHP, C++은 되는지 아직 확인은 안 해봤으나 C#은 되지 않을까 싶다.



1. 주제, 실험 환경


자바 JSP/Servlet으로 REST를 구축할 수 있는지 실험하였다.


- Apache Tomcat 9 - 2020년 9월 기준 - 최신

- Maven 3.6 - 2020년 9월 기준 - 최신

- 각종 RESTEasy 4.5.3 - 2020년 9월 기준 - 최신 (pom 셋팅)......



2. 내용 - POM.xml 설정 사항


<?xml version="1.0" encoding="UTF-8"?>


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>


  <groupId>com.restmaven</groupId>

  <artifactId>restWeb</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <packaging>war</packaging>


  <name>restWeb Maven Webapp</name>

  <!-- FIXME change it to the project's website -->

  <url>http://localhost</url>


  <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <maven.compiler.source>1.7</maven.compiler.source>

    <maven.compiler.target>1.7</maven.compiler.target>

  </properties>


  <dependencies>

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

      <version>4.11</version>

      <scope>test</scope>

    </dependency>

    

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->

<dependency>

    <groupId>javax.servlet</groupId>

    <artifactId>javax.servlet-api</artifactId>

    <version>4.0.1</version>

    <scope>provided</scope>

</dependency>

       

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-databind</artifactId>

    <version>2.11.2</version>

</dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-core</artifactId>

    <version>2.11.2</version>

</dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-annotations</artifactId>

    <version>2.11.2</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-core -->

<dependency>

    <groupId>org.jboss.resteasy</groupId>

    <artifactId>resteasy-core</artifactId>

    <version>4.5.8.Final</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jaxb-provider -->

<dependency>

    <groupId>org.jboss.resteasy</groupId>

    <artifactId>resteasy-jaxb-provider</artifactId>

    <version>4.5.8.Final</version>

</dependency>


<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jsapi -->

<dependency>

    <groupId>org.jboss.resteasy</groupId>

    <artifactId>resteasy-jsapi</artifactId>

    <version>4.5.8.Final</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jackson2-provider -->

<dependency>

    <groupId>org.jboss.resteasy</groupId>

    <artifactId>resteasy-jackson2-provider</artifactId>

    <version>4.5.8.Final</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-multipart-provider -->

<dependency>

    <groupId>org.jboss.resteasy</groupId>

    <artifactId>resteasy-multipart-provider</artifactId>

    <version>4.5.8.Final</version>

</dependency>

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->

<dependency>

    <groupId>commons-io</groupId>

    <artifactId>commons-io</artifactId>

    <version>2.8.0</version>

</dependency>

  

  </dependencies>

 


  <build>

    <finalName>restWeb</finalName>

    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->

      <plugins>

        <plugin>

          <artifactId>maven-clean-plugin</artifactId>

          <version>3.1.0</version>

        </plugin>

        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->

        <plugin>

          <artifactId>maven-resources-plugin</artifactId>

          <version>3.0.2</version>

        </plugin>

        <plugin>

          <artifactId>maven-compiler-plugin</artifactId>

          <version>3.8.0</version>

        </plugin>

        <plugin>

          <artifactId>maven-surefire-plugin</artifactId>

          <version>2.22.1</version>

        </plugin>

        <plugin>

          <artifactId>maven-war-plugin</artifactId>

          <version>3.2.2</version>

        </plugin>

        <plugin>

          <artifactId>maven-install-plugin</artifactId>

          <version>2.5.2</version>

        </plugin>

        <plugin>

          <artifactId>maven-deploy-plugin</artifactId>

          <version>2.8.2</version>

        </plugin>

      </plugins>

    </pluginManagement>

  </build>

</project>



파일명: pom.xml



3. 내용 - web.xml 설정 사항


<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

 

  <display-name>Archetype Created Web Application</display-name>

  

  <context-param>

  <param-name>resteasy.resources</param-name>

  <param-value>com.example.restweb.resources.MyResources</param-value>

  </context-param>

  <context-param>

  <param-name>resteasy.servlet.mapping.prefix</param-name>

  <param-value>/rest</param-value>

  </context-param>


  <listener>

  <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>

  </listener>


  <servlet>

  <servlet-name>Resteasy JSAPI</servlet-name>

<servlet-class>org.jboss.resteasy.jsapi.JSAPIServlet</servlet-class>

</servlet>

  <servlet-mapping>

  <servlet-name>Resteasy JSAPI</servlet-name>

  <url-pattern>/rest-js</url-pattern>

  </servlet-mapping>


  <servlet>

  <servlet-name>Resteasy</servlet-name>

  <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>

  </servlet>

  <servlet-mapping>

  <servlet-name>Resteasy</servlet-name>

  <url-pattern>/rest/*</url-pattern>

  </servlet-mapping>

 

  <servlet>

  <servlet-name>HomeServlet</servlet-name>

  <servlet-class>com.example.restweb.controller.HomeServlet</servlet-class>

  </servlet>

  <servlet-mapping>

  <servlet-name>HomeServlet</servlet-name>

  <url-pattern>/HomeServlet</url-pattern>

  </servlet-mapping>

  

</web-app>



파일명: web.xml



4. 내용 - 기본 컨트롤러 셋팅하기


RestEasy의 사용자 구현에서는 핵심이라고 보면 된다.

크게 사용방법에서는 어려운 건 아니다.


난해할 수 있는 주제가 있는데, String 등으로 바로 반환이 안 되는지.

고민해볼 수 있는 문제가 있다.


= "안 된다. 미지원이다."


Response로 무조건 return 반환을 해줘야 한다. 

(Spring Framework 5 - REST 공부하다가 이거 하라고 하면 납득이 안 될 수 있는 부분이 많다.)


package com.example.restweb.resources;


import com.example.restweb.model.FileInfo;


import javax.ws.rs.Consumes;

import javax.ws.rs.Encoded;

import javax.ws.rs.FormParam;

import javax.ws.rs.GET;

import javax.ws.rs.POST;

import javax.ws.rs.PUT;

import javax.ws.rs.Path;

import javax.ws.rs.PathParam;

import javax.ws.rs.Produces;

import javax.ws.rs.QueryParam;

import javax.ws.rs.core.Context;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Response;

import javax.ws.rs.core.UriInfo;


import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;


@Path("/api")

public class MyResources

{

// Index

@GET

@Path("")

    @Produces("application/json")

public Response get()

{

StringBuffer buf = new StringBuffer();

buf.append("ok");

return Response.status(200).entity(buf).build();

}


    @GET

    @Path("users/{id}")

    @Produces("application/json")

    public Response getUserById(@PathParam("id") Integer id)

    {

        User user = new User();

        user.setId(id);

        user.setFirstName("Lokesh");

        user.setLastName("Gupta");

        

        return Response.status(200).entity(user).build();

    }

    

    @Path("foo/{param}-{other}")

@PUT

    @Produces("application/json")

public Response putFooParam(@PathParam("param") String param,

  @PathParam("other") String other)

{

StringBuffer buf = new StringBuffer();

buf.append("param").append("=").append(param).append(";");

buf.append("other").append("=").append(other).append(";");

return Response.status(200).entity(buf).build();

}

    

@Path("form")

@POST

    @Produces("application/json")

public String postForm(@FormParam("id") String a,

   @FormParam("passwd") String b){

return a +"/" +b;

}


@Path("lookup")

@GET

    @Produces("application/json")

public Response lookup(@QueryParam("id") String id,

@Context UriInfo uriInfo)

{


StringBuffer buf = new StringBuffer();

buf.append("param").append("=").append(id).append(";");

return Response.status(200).entity(buf).build();

}


    @POST

    @Path("/upload-file")

    @Consumes(MediaType.MULTIPART_FORM_DATA)

    public Response uploadFile(@MultipartForm FileInfo info) throws Exception {

   

    String fileName = info.getFileName();

   

    // RESTEasy는 한글 자체가 안됨.

   

    /*

    form.setFileName(filename);

   

    System.out.println("파일명1:" + form.getFileName());

   

        String fileName = form.getFileName() == null ? "Unknown" : form.getFileName() ;

        String completeFilePath = "c:/temp2/" + fileName;

        try

        {

            //Save the file

            File file = new File(completeFilePath);

              

            if (!file.exists()) 

            {

                file.createNewFile();

            }

      

            FileOutputStream fos = new FileOutputStream(file);

      

            fos.write(form.getFileData());

            fos.flush();

            fos.close();

        } 

        catch (IOException e)

        {

            e.printStackTrace();

        }

        //Build a response to return

        */

   

        return Response.status(200)

            .entity("uploadFile is called, Uploaded file name : " + fileName).build();

        

   

    }

    

    

}


파일명: MyResources.java



5. 결과


실험1)

-> 문자셋 찾기 실험(UTF-8, Euc-kr, us-ascil, windows-1251, ISO-8851-9? 등)

    (반복문으로 해당 문자인지 찾는 작업을 하였음.)

(실패)


실험2)

-> <form 태그 accept- utf-8> 가능하도록 설정

(실패)


실험3)

-> new String (originalText.getBytes("ISO-8851-9), "UTF-8") 등 변환 작업

(실패)

.......

실험4)

-> public response 함수명(@Context ServletRequest req......)에 req.setCharacterEncoding 설정

(실패)



(다수의 방법을 적용하였음.)


결과는 RESTEasy 프로젝트에서 한글 자체를 해결해줘야 한다. 그렇지 않으면 어렵다.

이 프로그램은 영어로 글을 작성한다고 했을 때는 동작한다.


단순한 영어나 숫자 형태로 전송 작업을 시도하고 싶다면, 해봐도 무방하다. 한글 등은 기대 안 하는 게 좋을 듯 싶다.


RESTEasy 이외에 흥미로운 발견을 한 부분도 있다.

Servlet 생성할 때 셋팅화면에 자세히 보면, doPut, doDelete, doGet, doPost 기능이 있다.

문제는 패턴 등을 잡을 때 한계가 생긴다. (힘들고 무척 어렵다는 이야기이다.)


이 실험은 그런 부분은 해소하였다.




[첨부(Attachments)]

restEasy-한글미지원(Unsupported_Korean_Language).zip

(Spring Tool-Suite 4.4에서 작성함.)





* 참고자료(References)


1. RESTEasy JAX-RS, https://docs.jboss.org/resteasy/docs/4.5.8.Final/userguide/html/, Accessed by 2020-09-29, Last Modified 2020-09-23.

   = (RESTEasy 기술 정보가 해외, 국내에 많이 부족해서 공식 메뉴얼을 참고할 수 밖에 없음)


2. Chapter 3. Installation/Configuration, / 3.3. Deploying to other servlet containers, https://docs.jboss.org/resteasy/docs/4.5.8.Final/userguide/html/Installation_Configuration.html


3. RESTEasy JSON Example with Jackson, https://howtodoinjava.com/resteasy/resteasy-jackson-json-example/, Accessed by 2020-09-29, Last Modified 2013.

   = (RESTEasy에서의 다중 업로드 기능에 대해서는 잘 소개하고 있다.)


4. /resteasy/test/smoke/MyResource.java - Github, https://github.com/resteasy/resteasy-examples/blob/master/jsapi-servlet-test/src/main/java/org/jboss/resteasy/test/smoke/MyResource.java, Accessed by 2020-09-29, Last Modified 2016-08-05.

   = 조금 된 소스코드이나 RESTEasy를 쉽게 빠르게 구축하는 방법이 적혀져 있다.

   = 문제는 저 코드대로 전부 따라해보면, 안 된다. 태스트를 수 차례 각종 URL을 넣어봐서 되는 코드는 살리고 참고를 많이 하였다.


5. JSON Example With RESTEasy + Jackson, https://examples.javacodegeeks.com/enterprise-java/rest/resteasy/json-example-with-resteasy-jackson/, Accessed by 2020-09-29, Last Modified 2013-12-09

   = 구축 원리를 차근차근 화면 그림 위주로 소개하고 있다.


6. RESTEasy File Upload – Html Form Example, https://howtodoinjava.com/resteasy/jax-rs-resteasy-file-upload-html-form-example/, Accessed by 2020-09-29, Last Modified 2013.

   = RESTEasy 2.3 기반으로 작성된 것이라서 다소 일부분만 참고하였다. 동작이 안 되는 코드들도 많다.


7. RESTEasy JAX-RS 4.5.8.Final API, https://docs.jboss.org/resteasy/docs/4.5.8.Final/javadocs/, Accessed by 2020-09-29, Last Modified 2020-09.

   = JAVA API 메뉴얼처럼 RestEasy도 API 메뉴얼이 있다. 변화가 다소 있었다. 2.3버전의 메뉴얼과 현재 버전의 기능 변화가 많이 있었다.

반응형

+ Recent posts