{"id":1197,"date":"2025-03-24T08:52:37","date_gmt":"2025-03-23T23:52:37","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=1197"},"modified":"2025-03-24T08:52:37","modified_gmt":"2025-03-23T23:52:37","slug":"jax-rs%e3%81%a7%e9%ab%98%e6%80%a7%e8%83%bdrestful-api%e3%82%92%e4%bd%9c%e3%82%8b%ef%bc%81%e5%ae%9f%e8%b7%b5%e7%9a%84%e3%81%aa%e5%ae%9f%e8%a3%85%e6%96%b9%e6%b3%95%e3%81%a89%e3%81%a4%e3%81%ae%e3%83%99","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=1197","title":{"rendered":"JAX-RS\u3067\u9ad8\u6027\u80fdRESTful API\u3092\u4f5c\u308b\uff01\u5b9f\u8df5\u7684\u306a\u5b9f\u88c5\u65b9\u6cd5\u30689\u3064\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9"},"content":{"rendered":"\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">JAX-RS \u3068\u306f\uff1f\u57fa\u790e\u304b\u3089\u6700\u65b0\u52d5\u5411\u307e\u3067\u5b8c\u5168\u89e3\u8aac<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">JAX-RS \u306e\u6982\u8981\u3068\u4e3b\u8981\u306a\u7279\u5fb4<\/a>      <\/li>      <li>        <a href=\"#i-2\">Jakarta EE \u306b\u304a\u3051\u308b JAX-RS \u306e\u4f4d\u7f6e\u3065\u3051<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-3\">\u5f93\u6765\u306e\u30b5\u30fc\u30d0\u30fc\u30b5\u30a4\u30c9\u5b9f\u88c5\u3068\u306e\u6bd4\u8f03<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-4\">JAX-RS\u306b\u3088\u308bRESTful API\u958b\u767a\u306e\u57fa\u672c<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-5\">\u74b0\u5883\u69cb\u7bc9\u3068\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u624b\u9806<\/a>      <\/li>      <li>        <a href=\"#i-6\">\u57fa\u672c\u7684\u306a CRUD \u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-7\">\u30d1\u30b9\u3068\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u4ed5\u7d44\u307f<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-8\">\u5b9f\u8df5\u7684\u306a JAX-RS \u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-9\">\u52b9\u7387\u7684\u306a\u30ea\u30bd\u30fc\u30b9\u30af\u30e9\u30b9\u306e\u8a2d\u8a08\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-10\">\u4f8b\u5916\u51e6\u7406\u3068\u30a8\u30e9\u30fc\u5fdc\u7b54\u306e\u5b9f\u88c5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-11\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6a5f\u80fd\u306e\u6d3b\u7528\u8853<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-12\">JAX-RS\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b99\u9078<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-13\">\u9069\u5207\u306aHTTP\u30e1\u30bd\u30c3\u30c9\u3068\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u306e\u4f7f\u7528<\/a>      <\/li>      <li>        <a href=\"#i-14\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-15\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30dd\u30a4\u30f3\u30c8<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-16\">\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3068\u5b9f\u88c5\u4f8b<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-17\">\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u6a5f\u80fd\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-18\">\u975e\u540c\u671f\u51e6\u7406\u306e\u5b9f\u88c5\u65b9\u6cd5<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-19\">\u30ad\u30e3\u30c3\u30b7\u30e5\u5236\u5fa1\u306e\u5b9f\u8df5\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-20\">JAX-RS\u306b\u3088\u308b\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u958b\u767a<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-21\">\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u306b\u304a\u3051\u308b\u6d3b\u7528\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-22\">\u30b5\u30fc\u30d3\u30b9\u9593\u901a\u4fe1\u306e\u5b9f\u8df5\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-23\">\u30b3\u30f3\u30c6\u30ca\u5316\u3068\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u8003\u616e\u70b9<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">JAX-RS \u3068\u306f\uff1f\u57fa\u790e\u304b\u3089\u6700\u65b0\u52d5\u5411\u307e\u3067\u5b8c\u5168\u89e3\u8aac<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">JAX-RS \u306e\u6982\u8981\u3068\u4e3b\u8981\u306a\u7279\u5fb4<\/h3>\n\n\n\n<p>JAX-RS\uff08Jakarta RESTful Web Services\u3001\u65e7Java API for RESTful Web Services\uff09\u306f\u3001Java\u3067RESTful Web\u30b5\u30fc\u30d3\u30b9\u3092\u69cb\u7bc9\u3059\u308b\u305f\u3081\u306e\u6a19\u6e96\u4ed5\u69d8\u3067\u3059\u3002\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3\u30d9\u30fc\u30b9\u306e\u76f4\u611f\u7684\u306aAPI\u3092\u63d0\u4f9b\u3057\u3001REST\u539f\u5247\u306b\u57fa\u3065\u3044\u305fWeb\u30b5\u30fc\u30d3\u30b9\u306e\u958b\u767a\u3092\u5bb9\u6613\u306b\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u4e3b\u8981\u306a\u7279\u5fb4\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5ba3\u8a00\u7684\u306a\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>@Path<\/code>: \u30ea\u30bd\u30fc\u30b9\u306e\u30d1\u30b9\u3092\u6307\u5b9a<\/li>\n\n\n\n<li><code>@GET<\/code>, <code>@POST<\/code>, <code>@PUT<\/code>, <code>@DELETE<\/code>: HTTP\u30e1\u30bd\u30c3\u30c9\u3092\u5b9a\u7fa9<\/li>\n\n\n\n<li><code>@Produces<\/code>, <code>@Consumes<\/code>: \u30e1\u30c7\u30a3\u30a2\u30bf\u30a4\u30d7\u3092\u6307\u5b9a<\/li>\n\n\n\n<li><code>@PathParam<\/code>, <code>@QueryParam<\/code>: \u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u53d6\u5f97<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u67d4\u8edf\u306a\u30e1\u30c7\u30a3\u30a2\u30bf\u30a4\u30d7\u30b5\u30dd\u30fc\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>JSON, XML, \u30c6\u30ad\u30b9\u30c8\u7b49\u306e\u591a\u69d8\u306a\u5f62\u5f0f\u306b\u5bfe\u5fdc<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u30e1\u30c7\u30a3\u30a2\u30bf\u30a4\u30d7\u306e\u5b9a\u7fa9\u304c\u53ef\u80fd<\/li>\n\n\n\n<li>Content Negotiation\u306b\u3088\u308b\u52d5\u7684\u306a\u5f62\u5f0f\u9078\u629e<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d5\u30a3\u30eb\u30bf\u3068\u30a4\u30f3\u30bf\u30fc\u30bb\u30d7\u30bf<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30ea\u30af\u30a8\u30b9\u30c8\/\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u524d\u5f8c\u51e6\u7406\u304c\u53ef\u80fd<\/li>\n\n\n\n<li>\u30af\u30ed\u30b9\u30ab\u30c3\u30c6\u30a3\u30f3\u30b0\u30b3\u30f3\u30b5\u30fc\u30f3\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3001\u30ed\u30ae\u30f3\u30b0\u7b49\u306e\u6a5f\u80fd\u8ffd\u52a0<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u975e\u540c\u671f\u51e6\u7406\u306e\u30b5\u30dd\u30fc\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>@Suspended<\/code>\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3\u306b\u3088\u308b\u975e\u540c\u671f\u51e6\u7406<\/li>\n\n\n\n<li>Server-Sent Events\u306e\u30b5\u30dd\u30fc\u30c8<\/li>\n\n\n\n<li>WebSocket\u3068\u306e\u7d71\u5408<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">Jakarta EE \u306b\u304a\u3051\u308b JAX-RS \u306e\u4f4d\u7f6e\u3065\u3051<\/h3>\n\n\n\n<p>Jakarta EE\u30a8\u30b3\u30b7\u30b9\u30c6\u30e0\u306b\u304a\u3044\u3066\u3001JAX-RS\u306f\u91cd\u8981\u306a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3068\u3057\u3066\u4f4d\u7f6e\u3065\u3051\u3089\u308c\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Jakarta EE 9\u3067\u306e\u5909\u66f4\u70b9<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d1\u30c3\u30b1\u30fc\u30b8\u540d\u304c<code>javax.ws.rs<\/code>\u304b\u3089<code>jakarta.ws.rs<\/code>\u306b\u5909\u66f4<\/li>\n\n\n\n<li>\u3088\u308a\u67d4\u8edf\u306aDI\u30b5\u30dd\u30fc\u30c8<\/li>\n\n\n\n<li>\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u6307\u5411\u306e\u5f37\u5316<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4ed6\u306eJakarta EE\u6280\u8853\u3068\u306e\u7d71\u5408<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   @Path(\"\/users\")\n   @RequestScoped  \/\/ CDI\u30b9\u30b3\u30fc\u30d7\n   public class UserResource {\n       @Inject\n       private UserService userService;  \/\/ CDI\u306b\u3088\u308b\u4f9d\u5b58\u6027\u6ce8\u5165\n\n       @PersistenceContext\n       private EntityManager em;  \/\/ JPA\u3068\u306e\u7d71\u5408\n\n       @GET\n       @Produces(MediaType.APPLICATION_JSON)\n       public List&lt;User&gt; getUsers() {\n           return userService.findAll();\n       }\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u5b9f\u88c5\u30d9\u30f3\u30c0\u30fc<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Eclipse Jersey\uff08\u30ea\u30d5\u30a1\u30ec\u30f3\u30b9\u5b9f\u88c5\uff09<\/li>\n\n\n\n<li>RESTEasy\uff08Red Hat\uff09<\/li>\n\n\n\n<li>Apache CXF<\/li>\n\n\n\n<li>\u305d\u308c\u305e\u308c\u306e\u7279\u5fb4\u3068\u5229\u70b9\u3042\u308a<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-3\">\u5f93\u6765\u306e\u30b5\u30fc\u30d0\u30fc\u30b5\u30a4\u30c9\u5b9f\u88c5\u3068\u306e\u6bd4\u8f03<\/h3>\n\n\n\n<p>\u5f93\u6765\u306e\u30b5\u30fc\u30d6\u30ec\u30c3\u30c8\u30d9\u30fc\u30b9\u306e\u5b9f\u88c5\u3068JAX-RS\u3092\u6bd4\u8f03\u3057\u3066\u307f\u307e\u3057\u3087\u3046\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5f93\u6765\u306e\u30b5\u30fc\u30d6\u30ec\u30c3\u30c8\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@WebServlet(\"\/users\/*\")\npublic class UserServlet extends HttpServlet {\n    @Override\n    protected void doGet(HttpServletRequest req, HttpServletResponse resp) \n            throws ServletException, IOException {\n        String pathInfo = req.getPathInfo();\n        if (pathInfo == null || pathInfo.equals(\"\/\")) {\n            \/\/ \u5168\u30e6\u30fc\u30b6\u30fc\u306e\u53d6\u5f97\n            List&lt;User&gt; users = userService.findAll();\n            String json = new ObjectMapper().writeValueAsString(users);\n            resp.setContentType(\"application\/json\");\n            resp.getWriter().write(json);\n        } else {\n            \/\/ \u7279\u5b9a\u30e6\u30fc\u30b6\u30fc\u306e\u53d6\u5f97\n            Long id = Long.parseLong(pathInfo.substring(1));\n            User user = userService.findById(id);\n            if (user != null) {\n                String json = new ObjectMapper().writeValueAsString(user);\n                resp.setContentType(\"application\/json\");\n                resp.getWriter().write(json);\n            } else {\n                resp.sendError(HttpServletResponse.SC_NOT_FOUND);\n            }\n        }\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>JAX-RS\u306b\u3088\u308b\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/users\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class UserResource {\n    @Inject\n    private UserService userService;\n\n    @GET\n    public List&lt;User&gt; getAllUsers() {\n        return userService.findAll();\n    }\n\n    @GET\n    @Path(\"\/{id}\")\n    public Response getUserById(@PathParam(\"id\") Long id) {\n        return userService.findById(id)\n                .map(user -&gt; Response.ok(user).build())\n                .orElse(Response.status(Response.Status.NOT_FOUND).build());\n    }\n}<\/pre>\n\n\n\n<p>\u4e3b\u306a\u5229\u70b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5ba3\u8a00\u7684\u306aAPI\u8a2d\u8a08<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3\u306b\u3088\u308b\u76f4\u611f\u7684\u306a\u5b9f\u88c5<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u3068\u4fdd\u5b88\u6027\u306e\u5411\u4e0a<\/li>\n\n\n\n<li>\u30dc\u30a4\u30e9\u30fc\u30d7\u30ec\u30fc\u30c8\u30b3\u30fc\u30c9\u306e\u524a\u6e1b<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6a19\u6e96\u5316\u3055\u308c\u305f\u30a2\u30d7\u30ed\u30fc\u30c1<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>RESTful\u539f\u5247\u306b\u57fa\u3065\u3044\u305f\u4e00\u8cab\u3057\u305f\u8a2d\u8a08<\/li>\n\n\n\n<li>\u3055\u307e\u3056\u307e\u306a\u5b9f\u88c5\u30d9\u30f3\u30c0\u30fc\u9593\u3067\u306e\u4e92\u63db\u6027<\/li>\n\n\n\n<li>\u8c4a\u5bcc\u306a\u30a8\u30b3\u30b7\u30b9\u30c6\u30e0\u3068\u30c4\u30fc\u30eb\u306e\u30b5\u30dd\u30fc\u30c8<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u67d4\u8edf\u6027\u3068\u62e1\u5f35\u6027<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d5\u30a3\u30eb\u30bf\u3084\u30a4\u30f3\u30bf\u30fc\u30bb\u30d7\u30bf\u306b\u3088\u308b\u6a5f\u80fd\u62e1\u5f35<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u5b9f\u88c5\u304c\u5bb9\u6613<\/li>\n\n\n\n<li>\u69d8\u3005\u306a\u30e1\u30c7\u30a3\u30a2\u30bf\u30a4\u30d7\u3078\u306e\u5bfe\u5fdc<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306b\u3001JAX-RS\u306f\u5f93\u6765\u306e\u5b9f\u88c5\u65b9\u6cd5\u3068\u6bd4\u8f03\u3057\u3066\u3001\u3088\u308a\u52b9\u7387\u7684\u3067\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u6027\u306e\u9ad8\u3044RESTful Web\u30b5\u30fc\u30d3\u30b9\u306e\u958b\u767a\u3092\u53ef\u80fd\u306b\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-4\">JAX-RS\u306b\u3088\u308bRESTful API\u958b\u767a\u306e\u57fa\u672c<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">\u74b0\u5883\u69cb\u7bc9\u3068\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u624b\u9806<\/h3>\n\n\n\n<p>JAX-RS\u3092\u4f7f\u7528\u3057\u305fRESTful API\u958b\u767a\u3092\u59cb\u3081\u308b\u305f\u3081\u306e\u74b0\u5883\u69cb\u7bc9\u3068\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3092\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5fc5\u8981\u306a\u4f9d\u5b58\u95a2\u4fc2<\/strong><br>Maven project\u306e\u5834\u5408\u3001<code>pom.xml<\/code>\u306b\u4ee5\u4e0b\u306e\u4f9d\u5b58\u95a2\u4fc2\u3092\u8ffd\u52a0\u3057\u307e\u3059\uff1a<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;dependencies&gt;\n    &lt;!-- JAX-RS API --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;jakarta.ws.rs&lt;\/groupId&gt;\n        &lt;artifactId&gt;jakarta.ws.rs-api&lt;\/artifactId&gt;\n        &lt;version&gt;3.1.0&lt;\/version&gt;\n    &lt;\/dependency&gt;\n\n    &lt;!-- Jersey\uff08\u5b9f\u88c5\uff09 --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.glassfish.jersey.containers&lt;\/groupId&gt;\n        &lt;artifactId&gt;jersey-container-servlet&lt;\/artifactId&gt;\n        &lt;version&gt;3.1.1&lt;\/version&gt;\n    &lt;\/dependency&gt;\n\n    &lt;!-- Jersey DI support --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.glassfish.jersey.inject&lt;\/groupId&gt;\n        &lt;artifactId&gt;jersey-hk2&lt;\/artifactId&gt;\n        &lt;version&gt;3.1.1&lt;\/version&gt;\n    &lt;\/dependency&gt;\n\n    &lt;!-- JSON support --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.glassfish.jersey.media&lt;\/groupId&gt;\n        &lt;artifactId&gt;jersey-media-json-jackson&lt;\/artifactId&gt;\n        &lt;version&gt;3.1.1&lt;\/version&gt;\n    &lt;\/dependency&gt;\n&lt;\/dependencies&gt;<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u8a2d\u5b9a<\/strong><br>JAX-RS\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u57fa\u672c\u8a2d\u5b9a\uff1a<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@ApplicationPath(\"\/api\")\npublic class RestApplication extends Application {\n    @Override\n    public Set&lt;Class&lt;?&gt;&gt; getClasses() {\n        Set&lt;Class&lt;?&gt;&gt; resources = new HashSet&lt;&gt;();\n        \/\/ \u30ea\u30bd\u30fc\u30b9\u30af\u30e9\u30b9\u306e\u767b\u9332\n        resources.add(UserResource.class);\n        return resources;\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">\u57fa\u672c\u7684\u306a CRUD \u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30e6\u30fc\u30b6\u30fc\u7ba1\u7406API\u3092\u4f8b\u306b\u3001\u57fa\u672c\u7684\u306aCRUD\u64cd\u4f5c\u3092\u5b9f\u88c5\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/users\")\n@Produces(MediaType.APPLICATION_JSON)\n@Consumes(MediaType.APPLICATION_JSON)\npublic class UserResource {\n    private final UserService userService;\n\n    @Inject\n    public UserResource(UserService userService) {\n        this.userService = userService;\n    }\n\n    \/\/ Create\n    @POST\n    public Response createUser(User user) {\n        User created = userService.create(user);\n        return Response\n            .status(Response.Status.CREATED)\n            .entity(created)\n            .build();\n    }\n\n    \/\/ Read\n    @GET\n    public List&lt;User&gt; getAllUsers() {\n        return userService.findAll();\n    }\n\n    @GET\n    @Path(\"\/{id}\")\n    public Response getUserById(@PathParam(\"id\") Long id) {\n        return userService.findById(id)\n            .map(user -&gt; Response.ok(user).build())\n            .orElse(Response.status(Response.Status.NOT_FOUND).build());\n    }\n\n    \/\/ Update\n    @PUT\n    @Path(\"\/{id}\")\n    public Response updateUser(@PathParam(\"id\") Long id, User user) {\n        if (!id.equals(user.getId())) {\n            return Response.status(Response.Status.BAD_REQUEST).build();\n        }\n\n        User updated = userService.update(user);\n        return Response.ok(updated).build();\n    }\n\n    \/\/ Delete\n    @DELETE\n    @Path(\"\/{id}\")\n    public Response deleteUser(@PathParam(\"id\") Long id) {\n        userService.delete(id);\n        return Response.noContent().build();\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">\u30d1\u30b9\u3068\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u4ed5\u7d44\u307f<\/h3>\n\n\n\n<p>JAX-RS\u3067\u306f\u3001\u69d8\u3005\u306a\u65b9\u6cd5\u3067\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u53d7\u3051\u53d6\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d1\u30b9\u30d1\u30e9\u30e1\u30fc\u30bf<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/users\/{id}\/posts\/{postId}\")\npublic Response getUserPost(\n    @PathParam(\"id\") Long userId,\n    @PathParam(\"postId\") Long postId\n) {\n    \/\/ \u30d1\u30b9\u304b\u3089\u53d6\u5f97\u3057\u305f\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u4f7f\u7528\n    return Response.ok(postService.findUserPost(userId, postId)).build();\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30af\u30a8\u30ea\u30d1\u30e9\u30e1\u30fc\u30bf<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@GET\n@Path(\"\/search\")\npublic List&lt;User&gt; searchUsers(\n    @QueryParam(\"name\") String name,\n    @QueryParam(\"age\") Integer age,\n    @DefaultValue(\"0\") @QueryParam(\"page\") int page,\n    @DefaultValue(\"10\") @QueryParam(\"size\") int size\n) {\n    return userService.search(name, age, page, size);\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30de\u30c8\u30ea\u30c3\u30af\u30b9\u30d1\u30e9\u30e1\u30fc\u30bf<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@GET\n@Path(\"\/filter\")\npublic List&lt;User&gt; filterUsers(\n    @MatrixParam(\"country\") String country,\n    @MatrixParam(\"city\") String city\n) {\n    return userService.filter(country, city);\n}<\/pre>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>\u30d5\u30a9\u30fc\u30e0\u30d1\u30e9\u30e1\u30fc\u30bf<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@POST\n@Path(\"\/login\")\n@Consumes(MediaType.APPLICATION_FORM_URLENCODED)\npublic Response login(\n    @FormParam(\"username\") String username,\n    @FormParam(\"password\") String password\n) {\n    \/\/ \u30d5\u30a9\u30fc\u30e0\u30c7\u30fc\u30bf\u306e\u51e6\u7406\n    return authService.login(username, password);\n}<\/pre>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li><strong>\u30d8\u30c3\u30c0\u30fc\u30d1\u30e9\u30e1\u30fc\u30bf<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@GET\n@Path(\"\/secure\")\npublic Response getSecureResource(\n    @HeaderParam(\"Authorization\") String authHeader\n) {\n    \/\/ \u8a8d\u8a3c\u30d8\u30c3\u30c0\u30fc\u306e\u51e6\u7406\n    if (!authService.validateToken(authHeader)) {\n        return Response.status(Response.Status.UNAUTHORIZED).build();\n    }\n    return Response.ok(secureResource).build();\n}<\/pre>\n\n\n\n<p>\u5b9f\u88c5\u306e\u30dd\u30a4\u30f3\u30c8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u9069\u5207\u306aHTTP\u30e1\u30bd\u30c3\u30c9\u306e\u4f7f\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>GET: \u30ea\u30bd\u30fc\u30b9\u306e\u53d6\u5f97<\/li>\n\n\n\n<li>POST: \u65b0\u898f\u30ea\u30bd\u30fc\u30b9\u306e\u4f5c\u6210<\/li>\n\n\n\n<li>PUT: \u30ea\u30bd\u30fc\u30b9\u306e\u66f4\u65b0<\/li>\n\n\n\n<li>DELETE: \u30ea\u30bd\u30fc\u30b9\u306e\u524a\u9664<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u9069\u5207\u306a\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9<\/li>\n\n\n\n<li>\u30ec\u30b9\u30dd\u30f3\u30b9\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3<\/li>\n\n\n\n<li>\u30d8\u30c3\u30c0\u30fc\u60c5\u5831<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d1\u30e9\u30e1\u30fc\u30bf\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bean Validation\u306e\u6d3b\u7528<\/li>\n\n\n\n<li>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u57fa\u672c\u3092\u62bc\u3055\u3048\u308b\u3053\u3068\u3067\u3001\u5805\u7262\u306aRESTful API\u306e\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-8\">\u5b9f\u8df5\u7684\u306a JAX-RS \u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">\u52b9\u7387\u7684\u306a\u30ea\u30bd\u30fc\u30b9\u30af\u30e9\u30b9\u306e\u8a2d\u8a08\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u52b9\u7387\u7684\u306a\u30ea\u30bd\u30fc\u30b9\u30af\u30e9\u30b9\u3092\u8a2d\u8a08\u3059\u308b\u305f\u3081\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ec\u30a4\u30e4\u30fc\u5206\u96e2\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/orders\")\n@Produces(MediaType.APPLICATION_JSON)\n@Consumes(MediaType.APPLICATION_JSON)\npublic class OrderResource {\n    private final OrderService orderService;\n    private final OrderMapper orderMapper;\n\n    @Inject\n    public OrderResource(OrderService orderService, OrderMapper orderMapper) {\n        this.orderService = orderService;\n        this.orderMapper = orderMapper;\n    }\n\n    @POST\n    public Response createOrder(OrderDTO orderDTO) {\n        \/\/ DTO\u304b\u3089\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u3078\u306e\u5909\u63db\n        Order order = orderMapper.toEntity(orderDTO);\n\n        \/\/ \u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u5b9f\u884c\n        Order created = orderService.createOrder(order);\n\n        \/\/ \u30ec\u30b9\u30dd\u30f3\u30b9DTO\u306e\u4f5c\u6210\n        OrderDTO response = orderMapper.toDTO(created);\n\n        return Response.status(Response.Status.CREATED)\n                      .entity(response)\n                      .build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30b5\u30d6\u30ea\u30bd\u30fc\u30b9\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/departments\")\npublic class DepartmentResource {\n    @Path(\"\/{deptId}\/employees\")\n    public EmployeeSubResource getEmployeeResource(@PathParam(\"deptId\") Long deptId) {\n        return new EmployeeSubResource(deptId);\n    }\n}\n\npublic class EmployeeSubResource {\n    private final Long departmentId;\n\n    public EmployeeSubResource(Long departmentId) {\n        this.departmentId = departmentId;\n    }\n\n    @GET\n    public List&lt;Employee&gt; getEmployees() {\n        return employeeService.findByDepartment(departmentId);\n    }\n\n    @POST\n    public Response addEmployee(Employee employee) {\n        employee.setDepartmentId(departmentId);\n        return Response.ok(employeeService.create(employee)).build();\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u4f8b\u5916\u51e6\u7406\u3068\u30a8\u30e9\u30fc\u5fdc\u7b54\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u4f8b\u5916\u30af\u30e9\u30b9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class BusinessException extends RuntimeException {\n    private final ErrorCode errorCode;\n\n    public BusinessException(ErrorCode errorCode, String message) {\n        super(message);\n        this.errorCode = errorCode;\n    }\n\n    public ErrorCode getErrorCode() {\n        return errorCode;\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30b0\u30ed\u30fc\u30d0\u30eb\u4f8b\u5916\u30cf\u30f3\u30c9\u30e9\u30fc<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Provider\npublic class GlobalExceptionHandler implements ExceptionMapper&lt;Throwable&gt; {\n\n    @Override\n    public Response toResponse(Throwable exception) {\n        if (exception instanceof BusinessException) {\n            BusinessException be = (BusinessException) exception;\n            ErrorResponse error = new ErrorResponse(\n                be.getErrorCode().getCode(),\n                be.getMessage()\n            );\n            return Response.status(Response.Status.BAD_REQUEST)\n                          .entity(error)\n                          .build();\n        }\n\n        if (exception instanceof ConstraintViolationException) {\n            ConstraintViolationException cve = (ConstraintViolationException) exception;\n            List&lt;String&gt; violations = cve.getConstraintViolations()\n                .stream()\n                .map(ConstraintViolation::getMessage)\n                .collect(Collectors.toList());\n\n            return Response.status(Response.Status.BAD_REQUEST)\n                          .entity(new ValidationErrorResponse(violations))\n                          .build();\n        }\n\n        \/\/ \u305d\u306e\u4ed6\u306e\u4f8b\u5916\u306f\u30b5\u30fc\u30d0\u30fc\u30a8\u30e9\u30fc\u3068\u3057\u3066\u51e6\u7406\n        return Response.status(Response.Status.INTERNAL_SERVER_ERROR)\n                      .entity(new ErrorResponse(\"INTERNAL_ERROR\", \"\u5185\u90e8\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\"))\n                      .build();\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-11\">\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6a5f\u80fd\u306e\u6d3b\u7528\u8853<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Bean Validation\u306e\u5229\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class UserDTO {\n    @NotNull(message = \"\u540d\u524d\u306f\u5fc5\u9808\u3067\u3059\")\n    @Size(min = 2, max = 100, message = \"\u540d\u524d\u306f2\u6587\u5b57\u4ee5\u4e0a100\u6587\u5b57\u4ee5\u5185\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\")\n    private String name;\n\n    @Email(message = \"\u6709\u52b9\u306a\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\")\n    private String email;\n\n    @Min(value = 0, message = \"\u5e74\u9f62\u306f0\u4ee5\u4e0a\u306e\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\")\n    @Max(value = 150, message = \"\u5e74\u9f62\u306f150\u4ee5\u4e0b\u306e\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\")\n    private Integer age;\n\n    \/\/ getter\/setter\n}\n\n@Path(\"\/users\")\npublic class UserResource {\n    @POST\n    public Response createUser(@Valid UserDTO userDTO) {\n        \/\/ \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u6e08\u307f\u306eDTO\u3092\u4f7f\u7528\n        return Response.ok(userService.create(userDTO)).build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ab\u30b9\u30bf\u30e0\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Target({ElementType.FIELD})\n@Retention(RetentionPolicy.RUNTIME)\n@Constraint(validatedBy = UniqueEmailValidator.class)\npublic @interface UniqueEmail {\n    String message() default \"\u3053\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u65e2\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\";\n    Class&lt;?&gt;[] groups() default {};\n    Class&lt;? extends Payload&gt;[] payload() default {};\n}\n\npublic class UniqueEmailValidator implements ConstraintValidator&lt;UniqueEmail, String&gt; {\n    @Inject\n    private UserService userService;\n\n    @Override\n    public boolean isValid(String email, ConstraintValidatorContext context) {\n        if (email == null) {\n            return true;\n        }\n        return !userService.existsByEmail(email);\n    }\n}\n\npublic class UserDTO {\n    @UniqueEmail\n    private String email;\n    \/\/ \u4ed6\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30b0\u30eb\u30fc\u30d7\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public interface CreateValidation {}\npublic interface UpdateValidation {}\n\npublic class ProductDTO {\n    @Null(groups = CreateValidation.class)\n    @NotNull(groups = UpdateValidation.class)\n    private Long id;\n\n    @NotNull(groups = {CreateValidation.class, UpdateValidation.class})\n    @Size(min = 3, max = 100)\n    private String name;\n\n    @NotNull(groups = CreateValidation.class)\n    @Positive\n    private BigDecimal price;\n}\n\n@Path(\"\/products\")\npublic class ProductResource {\n    @POST\n    public Response createProduct(\n        @Valid @Validated(CreateValidation.class) ProductDTO product\n    ) {\n        return Response.ok(productService.create(product)).build();\n    }\n\n    @PUT\n    @Path(\"\/{id}\")\n    public Response updateProduct(\n        @PathParam(\"id\") Long id,\n        @Valid @Validated(UpdateValidation.class) ProductDTO product\n    ) {\n        return Response.ok(productService.update(id, product)).build();\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u5805\u7262\u306aAPI\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u5404\u6a5f\u80fd\u3092\u9069\u6750\u9069\u6240\u3067\u4f7f\u7528\u3057\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8981\u4ef6\u306b\u5408\u308f\u305b\u3066\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-12\">JAX-RS\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b99\u9078<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u9069\u5207\u306aHTTP\u30e1\u30bd\u30c3\u30c9\u3068\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u306e\u4f7f\u7528<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>HTTP\u30e1\u30bd\u30c3\u30c9\u306e\u9069\u5207\u306a\u9078\u629e<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/articles\")\npublic class ArticleResource {\n    \/\/ \u51aa\u7b49\u6027\u306e\u3042\u308b\u64cd\u4f5c\u306b\u306fGET\u3092\u4f7f\u7528\n    @GET\n    @Path(\"\/{id}\")\n    public Response getArticle(@PathParam(\"id\") Long id) {\n        return articleService.findById(id)\n            .map(Response::ok)\n            .orElse(Response.status(Response.Status.NOT_FOUND))\n            .build();\n    }\n\n    \/\/ \u30ea\u30bd\u30fc\u30b9\u4f5c\u6210\u306b\u306fPOST\u3092\u4f7f\u7528\n    @POST\n    public Response createArticle(ArticleDTO article) {\n        Article created = articleService.create(article);\n        return Response.status(Response.Status.CREATED)\n            .entity(created)\n            .location(URI.create(\"\/articles\/\" + created.getId()))\n            .build();\n    }\n\n    \/\/ \u5b8c\u5168\u306a\u66f4\u65b0\u306b\u306fPUT\u3092\u4f7f\u7528\n    @PUT\n    @Path(\"\/{id}\")\n    public Response updateArticle(@PathParam(\"id\") Long id, ArticleDTO article) {\n        Article updated = articleService.update(id, article);\n        return Response.ok(updated).build();\n    }\n\n    \/\/ \u90e8\u5206\u66f4\u65b0\u306b\u306fPATCH\u3092\u4f7f\u7528\n    @PATCH\n    @Path(\"\/{id}\")\n    public Response patchArticle(@PathParam(\"id\") Long id, JsonPatch patch) {\n        Article patched = articleService.patch(id, patch);\n        return Response.ok(patched).build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u9069\u5207\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u306e\u4f7f\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Provider\npublic class ResponseStatusHandler implements ResponseStatusMapper {\n    public Response toResponse(Status status) {\n        switch (status) {\n            case SUCCESS:\n                return Response.status(Response.Status.OK).build();\n            case CREATED:\n                return Response.status(Response.Status.CREATED).build();\n            case NOT_FOUND:\n                return Response.status(Response.Status.NOT_FOUND)\n                    .entity(new ErrorResponse(\"Resource not found\"))\n                    .build();\n            case VALIDATION_ERROR:\n                return Response.status(Response.Status.BAD_REQUEST)\n                    .entity(new ErrorResponse(\"Validation failed\"))\n                    .build();\n            default:\n                return Response.status(Response.Status.INTERNAL_SERVER_ERROR)\n                    .entity(new ErrorResponse(\"Internal server error\"))\n                    .build();\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h3>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u30d5\u30a3\u30eb\u30bf\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Provider\n@Priority(Priorities.AUTHENTICATION)\npublic class JWTAuthenticationFilter implements ContainerRequestFilter {\n    @Override\n    public void filter(ContainerRequestContext requestContext) throws IOException {\n        String authHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);\n\n        if (authHeader == null || !authHeader.startsWith(\"Bearer \")) {\n            throw new NotAuthorizedException(\"\u8a8d\u8a3c\u30c8\u30fc\u30af\u30f3\u304c\u5fc5\u8981\u3067\u3059\");\n        }\n\n        String token = authHeader.substring(\"Bearer \".length());\n        try {\n            \/\/ \u30c8\u30fc\u30af\u30f3\u306e\u691c\u8a3c\n            Claims claims = validateToken(token);\n            \/\/ \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e\u8a2d\u5b9a\n            SecurityContext securityContext = new JWTSecurityContext(claims);\n            requestContext.setSecurityContext(securityContext);\n        } catch (Exception e) {\n            throw new NotAuthorizedException(\"\u7121\u52b9\u306a\u30c8\u30fc\u30af\u30f3\u3067\u3059\");\n        }\n    }\n}<\/pre>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>CORS\u8a2d\u5b9a\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Provider\npublic class CORSFilter implements ContainerResponseFilter {\n    @Override\n    public void filter(ContainerRequestContext requestContext,\n                      ContainerResponseContext responseContext) {\n        responseContext.getHeaders().add(\"Access-Control-Allow-Origin\", \"https:\/\/example.com\");\n        responseContext.getHeaders().add(\"Access-Control-Allow-Methods\", \n            \"GET, POST, PUT, DELETE, OPTIONS\");\n        responseContext.getHeaders().add(\"Access-Control-Allow-Headers\",\n            \"Content-Type, Authorization\");\n        responseContext.getHeaders().add(\"Access-Control-Max-Age\", \"86400\");\n    }\n}<\/pre>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li><strong>\u5165\u529b\u306e\u30b5\u30cb\u30bf\u30a4\u30ba<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class InputSanitizer {\n    public static String sanitize(String input) {\n        if (input == null) {\n            return null;\n        }\n        \/\/ XSS\u3092\u9632\u3050\u305f\u3081\u306e\u57fa\u672c\u7684\u306a\u30b5\u30cb\u30bf\u30a4\u30ba\n        return input.replaceAll(\"&lt;\", \"&amp;lt;\")\n                   .replaceAll(\"&gt;\", \"&amp;gt;\")\n                   .replaceAll(\"\\\"\", \"&amp;quot;\")\n                   .replaceAll(\"'\", \"&amp;#x27;\")\n                   .replaceAll(\"&amp;\", \"&amp;amp;\");\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30dd\u30a4\u30f3\u30c8<\/h3>\n\n\n\n<ol start=\"6\" class=\"wp-block-list\">\n<li><strong>\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/cached-resources\")\npublic class CachedResource {\n    @GET\n    @Path(\"\/{id}\")\n    @Produces(MediaType.APPLICATION_JSON)\n    public Response getCachedResource(@PathParam(\"id\") Long id) {\n        CachedEntity entity = resourceService.getById(id);\n\n        \/\/ ETag\u306e\u751f\u6210\n        EntityTag etag = new EntityTag(String.valueOf(entity.hashCode()));\n\n        \/\/ \u6761\u4ef6\u4ed8\u304dGET\u306e\u30c1\u30a7\u30c3\u30af\n        Response.ResponseBuilder rb = request.evaluatePreconditions(etag);\n        if (rb != null) {\n            return rb.build();\n        }\n\n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u30d8\u30c3\u30c0\u30fc\u306e\u8a2d\u5b9a\n        return Response.ok(entity)\n            .tag(etag)\n            .cacheControl(CacheControl.valueOf(\"max-age=3600\"))\n            .build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li><strong>\u30da\u30fc\u30b8\u30cd\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/items\")\npublic class ItemResource {\n    @GET\n    public Response getItems(\n        @QueryParam(\"page\") @DefaultValue(\"0\") int page,\n        @QueryParam(\"size\") @DefaultValue(\"20\") int size,\n        @QueryParam(\"sort\") @DefaultValue(\"id,desc\") String sort\n    ) {\n        Pageable pageable = PageRequest.of(page, size, Sort.by(sort.split(\",\")));\n        Page&lt;Item&gt; items = itemService.findAll(pageable);\n\n        return Response.ok(items)\n            .header(\"X-Total-Count\", items.getTotalElements())\n            .header(\"X-Total-Pages\", items.getTotalPages())\n            .build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"8\" class=\"wp-block-list\">\n<li><strong>\u975e\u540c\u671f\u51e6\u7406\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/async\")\npublic class AsyncResource {\n    @GET\n    @Path(\"\/process\")\n    public void asyncProcess(\n        @Suspended final AsyncResponse asyncResponse\n    ) {\n        CompletableFuture.supplyAsync(() -&gt; {\n            \/\/ \u6642\u9593\u306e\u304b\u304b\u308b\u51e6\u7406\n            return heavyProcess();\n        }).thenAccept(result -&gt; {\n            asyncResponse.resume(Response.ok(result).build());\n        }).exceptionally(throwable -&gt; {\n            asyncResponse.resume(Response.status(Response.Status.INTERNAL_SERVER_ERROR)\n                .entity(new ErrorResponse(throwable.getMessage()))\n                .build());\n            return null;\n        });\n    }\n}<\/pre>\n\n\n\n<ol start=\"9\" class=\"wp-block-list\">\n<li><strong>\u30d0\u30c3\u30c1\u51e6\u7406\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/batch\")\npublic class BatchResource {\n    @POST\n    @Path(\"\/operations\")\n    public Response batchOperations(List&lt;Operation&gt; operations) {\n        List&lt;CompletableFuture&lt;OperationResult&gt;&gt; futures = operations.stream()\n            .map(operation -&gt; CompletableFuture.supplyAsync(() -&gt; \n                processOperation(operation)))\n            .collect(Collectors.toList());\n\n        \/\/ \u5168\u3066\u306e\u51e6\u7406\u304c\u5b8c\u4e86\u3059\u308b\u306e\u3092\u5f85\u3064\n        List&lt;OperationResult&gt; results = futures.stream()\n            .map(CompletableFuture::join)\n            .collect(Collectors.toList());\n\n        return Response.ok(new BatchResponse(results)).build();\n    }\n\n    private OperationResult processOperation(Operation operation) {\n        try {\n            return operationService.process(operation);\n        } catch (Exception e) {\n            return new OperationResult(operation.getId(), Status.FAILED, e.getMessage());\n        }\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u30bb\u30ad\u30e5\u30a2\u3067\u9ad8\u6027\u80fd\u306aRESTful API\u3092\u69cb\u7bc9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u5b9f\u88c5\u306e\u969b\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8981\u4ef6\u3084\u5236\u7d04\u306b\u5fdc\u3058\u3066\u3001\u3053\u308c\u3089\u306e\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u9069\u5207\u306b\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-16\">\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3068\u5b9f\u88c5\u4f8b<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u6a5f\u80fd\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b7\u30f3\u30b0\u30eb\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/files\")\npublic class FileUploadResource {\n    @POST\n    @Path(\"\/upload\")\n    @Consumes(MediaType.MULTIPART_FORM_DATA)\n    public Response uploadFile(\n        @FormDataParam(\"file\") InputStream fileInputStream,\n        @FormDataParam(\"file\") FormDataContentDisposition fileMetaData\n    ) {\n        try {\n            \/\/ \u30d5\u30a1\u30a4\u30eb\u540d\u306e\u53d6\u5f97\u3068\u5b89\u5168\u6027\u30c1\u30a7\u30c3\u30af\n            String fileName = fileMetaData.getFileName();\n            if (!isValidFileName(fileName)) {\n                return Response.status(Response.Status.BAD_REQUEST)\n                    .entity(\"Invalid file name\")\n                    .build();\n            }\n\n            \/\/ \u30d5\u30a1\u30a4\u30eb\u306e\u4fdd\u5b58\n            String savedPath = saveFile(fileInputStream, fileName);\n\n            \/\/ \u30e1\u30bf\u30c7\u30fc\u30bf\u306e\u4fdd\u5b58\n            FileMetadata metadata = new FileMetadata();\n            metadata.setFileName(fileName);\n            metadata.setPath(savedPath);\n            metadata.setUploadDate(LocalDateTime.now());\n            fileMetadataRepository.save(metadata);\n\n            return Response.status(Response.Status.CREATED)\n                .entity(metadata)\n                .build();\n        } catch (IOException e) {\n            return Response.serverError()\n                .entity(\"Failed to upload file\")\n                .build();\n        }\n    }\n\n    private String saveFile(InputStream inputStream, String fileName) throws IOException {\n        String uploadDir = System.getProperty(\"user.home\") + \"\/uploads\/\";\n        Files.createDirectories(Paths.get(uploadDir));\n\n        String uniqueFileName = UUID.randomUUID().toString() + \"_\" + fileName;\n        Path filePath = Paths.get(uploadDir, uniqueFileName);\n\n        Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);\n        return filePath.toString();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30de\u30eb\u30c1\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@POST\n@Path(\"\/upload\/multiple\")\n@Consumes(MediaType.MULTIPART_FORM_DATA)\npublic Response uploadMultipleFiles(\n    MultivaluedMap&lt;String, FormDataBodyPart&gt; formData\n) {\n    List&lt;FileMetadata&gt; uploadedFiles = new ArrayList&lt;&gt;();\n\n    for (Map.Entry&lt;String, List&lt;FormDataBodyPart&gt;&gt; entry : formData.entrySet()) {\n        for (FormDataBodyPart bodyPart : entry.getValue()) {\n            if (bodyPart.getContentDisposition().getType().equals(\"attachment\")) {\n                try {\n                    InputStream fileStream = bodyPart.getValueAs(InputStream.class);\n                    String fileName = bodyPart.getContentDisposition().getFileName();\n\n                    String savedPath = saveFile(fileStream, fileName);\n                    FileMetadata metadata = createFileMetadata(fileName, savedPath);\n                    uploadedFiles.add(metadata);\n                } catch (IOException e) {\n                    \/\/ \u30a8\u30e9\u30fc\u30ed\u30b0\u306e\u8a18\u9332\n                    continue;\n                }\n            }\n        }\n    }\n\n    return Response.status(Response.Status.CREATED)\n        .entity(uploadedFiles)\n        .build();\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">\u975e\u540c\u671f\u51e6\u7406\u306e\u5b9f\u88c5\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u975e\u540c\u671fAPI\u51e6\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/async\")\npublic class AsyncResource {\n    @Inject\n    private ExecutorService executorService;\n\n    @GET\n    @Path(\"\/long-running\")\n    public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) {\n        \/\/ \u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u306e\u8a2d\u5b9a\n        asyncResponse.setTimeout(30, TimeUnit.SECONDS);\n        asyncResponse.setTimeoutHandler(ar -&gt; \n            ar.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)\n                .entity(\"Operation timed out\")\n                .build())\n        );\n\n        executorService.submit(() -&gt; {\n            try {\n                \/\/ \u6642\u9593\u306e\u304b\u304b\u308b\u51e6\u7406\n                Result result = performLongRunningTask();\n                asyncResponse.resume(Response.ok(result).build());\n            } catch (Exception e) {\n                asyncResponse.resume(Response.status(Response.Status.INTERNAL_SERVER_ERROR)\n                    .entity(e.getMessage())\n                    .build());\n            }\n        });\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Server-Sent Events (SSE)\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/sse\")\npublic class SSEResource {\n    @GET\n    @Produces(MediaType.SERVER_SENT_EVENTS)\n    public void subscribeToEvents(@Context SseEventSink eventSink, @Context Sse sse) {\n        ExecutorService executor = Executors.newSingleThreadExecutor();\n        executor.execute(() -&gt; {\n            try (SseEventSink sink = eventSink) {\n                for (int i = 0; i &lt; 10; i++) {\n                    OutboundSseEvent event = sse.newEventBuilder()\n                        .id(String.valueOf(i))\n                        .data(String.class, \"Event \" + i)\n                        .build();\n\n                    sink.send(event);\n                    Thread.sleep(1000);\n                }\n            } catch (InterruptedException e) {\n                \/\/ \u30a8\u30e9\u30fc\u51e6\u7406\n            }\n        });\n        executor.shutdown();\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-19\">\u30ad\u30e3\u30c3\u30b7\u30e5\u5236\u5fa1\u306e\u5b9f\u8df5\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>ETags \u3068\u6761\u4ef6\u4ed8\u304d\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/cached\")\npublic class CachedResource {\n    @GET\n    @Path(\"\/{id}\")\n    public Response getResource(\n        @PathParam(\"id\") Long id,\n        @Context Request request\n    ) {\n        Resource resource = resourceService.findById(id);\n        if (resource == null) {\n            return Response.status(Response.Status.NOT_FOUND).build();\n        }\n\n        \/\/ ETAG\u306e\u751f\u6210\n        EntityTag etag = new EntityTag(Integer.toString(resource.hashCode()));\n\n        \/\/ \u6761\u4ef6\u4ed8\u304dGET\u306e\u30c1\u30a7\u30c3\u30af\n        Response.ResponseBuilder rb = request.evaluatePreconditions(etag);\n        if (rb != null) {\n            return rb.build();\n        }\n\n        \/\/ \u30ad\u30e3\u30c3\u30b7\u30e5\u30d8\u30c3\u30c0\u30fc\u306e\u8a2d\u5b9a\n        CacheControl cc = new CacheControl();\n        cc.setMaxAge(3600);  \/\/ 1\u6642\u9593\n        cc.setPrivate(true);\n\n        return Response.ok(resource)\n            .tag(etag)\n            .cacheControl(cc)\n            .build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u52d5\u7684\u306a\u30ad\u30e3\u30c3\u30b7\u30e5\u5236\u5fa1<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Provider\npublic class DynamicCacheControlFilter implements ContainerResponseFilter {\n    @Override\n    public void filter(ContainerRequestContext requestContext,\n                      ContainerResponseContext responseContext) {\n        String path = requestContext.getUriInfo().getPath();\n\n        CacheControl cc = new CacheControl();\n\n        \/\/ \u30d1\u30b9\u306b\u57fa\u3065\u3044\u3066\u30ad\u30e3\u30c3\u30b7\u30e5\u6226\u7565\u3092\u6c7a\u5b9a\n        if (path.startsWith(\"\/api\/public\")) {\n            \/\/ \u516c\u958bAPI\u306f\u9577\u3081\u306b\u30ad\u30e3\u30c3\u30b7\u30e5\n            cc.setMaxAge(3600);\n            cc.setPrivate(false);\n        } else if (path.startsWith(\"\/api\/user\")) {\n            \/\/ \u30e6\u30fc\u30b6\u30fc\u56fa\u6709\u306e\u30c7\u30fc\u30bf\u306f\u77ed\u3081\u306b\u30ad\u30e3\u30c3\u30b7\u30e5\n            cc.setMaxAge(300);\n            cc.setPrivate(true);\n        } else {\n            \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u306f\u30ad\u30e3\u30c3\u30b7\u30e5\u306a\u3057\n            cc.setNoCache(true);\n        }\n\n        responseContext.getHeaders().add(\"Cache-Control\", cc);\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u6761\u4ef6\u4ed8\u304d\u66f4\u65b0\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/resources\")\npublic class ConditionalUpdateResource {\n    @PUT\n    @Path(\"\/{id}\")\n    public Response updateResource(\n        @PathParam(\"id\") Long id,\n        @HeaderParam(\"If-Match\") String ifMatch,\n        ResourceDTO resourceDTO\n    ) {\n        Resource currentResource = resourceService.findById(id);\n        if (currentResource == null) {\n            return Response.status(Response.Status.NOT_FOUND).build();\n        }\n\n        \/\/ ETAG\u306e\u691c\u8a3c\n        EntityTag currentEtag = new EntityTag(\n            Integer.toString(currentResource.hashCode())\n        );\n        if (ifMatch != null &amp;&amp; !ifMatch.equals(currentEtag.getValue())) {\n            return Response.status(Response.Status.PRECONDITION_FAILED)\n                .entity(\"Resource has been modified\")\n                .build();\n        }\n\n        \/\/ \u30ea\u30bd\u30fc\u30b9\u306e\u66f4\u65b0\n        Resource updatedResource = resourceService.update(id, resourceDTO);\n\n        \/\/ \u65b0\u3057\u3044ETAG\u306e\u751f\u6210\n        EntityTag newEtag = new EntityTag(\n            Integer.toString(updatedResource.hashCode())\n        );\n\n        return Response.ok(updatedResource)\n            .tag(newEtag)\n            .build();\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u4f8b\u306f\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u3088\u304f\u5fc5\u8981\u3068\u3055\u308c\u308b\u6a5f\u80fd\u3092\u52b9\u7387\u7684\u306b\u5b9f\u88c5\u3059\u308b\u65b9\u6cd5\u3092\u793a\u3057\u3066\u3044\u307e\u3059\u3002\u5404\u5b9f\u88c5\u306b\u306f\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3001\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306a\u3069\u306e\u91cd\u8981\u306a\u8003\u616e\u4e8b\u9805\u304c\u542b\u307e\u308c\u3066\u304a\u308a\u3001\u5b9f\u52d9\u3067\u5373\u5ea7\u306b\u6d3b\u7528\u3067\u304d\u308b\u5f62\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-20\">JAX-RS\u306b\u3088\u308b\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u958b\u767a<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u306b\u304a\u3051\u308b\u6d3b\u7528\u65b9\u6cd5<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u306e\u57fa\u672c\u69cb\u9020<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/orders\")\n@Produces(MediaType.APPLICATION_JSON)\n@Consumes(MediaType.APPLICATION_JSON)\npublic class OrderService {\n    @Inject\n    private OrderRepository orderRepository;\n\n    @Inject\n    @RestClient  \/\/ MicroProfile Rest Client\n    private PaymentService paymentService;\n\n    @Inject\n    @RestClient\n    private InventoryService inventoryService;\n\n    @POST\n    public Response createOrder(OrderRequest request) {\n        \/\/ \u5728\u5eab\u78ba\u8a8d\n        InventoryStatus status = inventoryService.checkInventory(\n            request.getProductId(),\n            request.getQuantity()\n        );\n\n        if (!status.isAvailable()) {\n            return Response.status(Response.Status.CONFLICT)\n                .entity(new ErrorResponse(\"\u5546\u54c1\u5728\u5eab\u4e0d\u8db3\"))\n                .build();\n        }\n\n        \/\/ \u652f\u6255\u3044\u51e6\u7406\n        PaymentResult payment = paymentService.processPayment(\n            request.getPaymentDetails()\n        );\n\n        if (!payment.isSuccessful()) {\n            return Response.status(Response.Status.BAD_REQUEST)\n                .entity(new ErrorResponse(\"\u652f\u6255\u3044\u51e6\u7406\u5931\u6557\"))\n                .build();\n        }\n\n        \/\/ \u6ce8\u6587\u4f5c\u6210\n        Order order = orderRepository.create(\n            new Order(request, payment.getTransactionId())\n        );\n\n        return Response.status(Response.Status.CREATED)\n            .entity(order)\n            .build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30b5\u30fc\u30d3\u30b9\u30c7\u30a3\u30b9\u30ab\u30d0\u30ea\u306e\u7d71\u5408<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@ApplicationScoped\npublic class ServiceDiscoveryConfig {\n    @Inject\n    private ConsulClient consulClient;\n\n    public void registerService() {\n        Registration registration = Registration.builder()\n            .id(\"order-service-\" + UUID.randomUUID())\n            .name(\"order-service\")\n            .address(\"localhost\")\n            .port(8080)\n            .check(Registration.RegCheck.http(\"\/health\", 10))\n            .build();\n\n        consulClient.agentServiceRegister(registration);\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u30b5\u30fc\u30d3\u30b9\u9593\u901a\u4fe1\u306e\u5b9f\u8df5\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>MicroProfile Rest Client\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/payment\")\n@RegisterRestClient(configKey=\"payment-api\")\npublic interface PaymentService {\n    @POST\n    @Path(\"\/process\")\n    PaymentResult processPayment(PaymentDetails details);\n\n    @GET\n    @Path(\"\/status\/{id}\")\n    PaymentStatus getPaymentStatus(@PathParam(\"id\") String transactionId);\n}\n\n@Path(\"\/inventory\")\n@RegisterRestClient(configKey=\"inventory-api\")\npublic interface InventoryService {\n    @GET\n    @Path(\"\/check\/{productId}\")\n    InventoryStatus checkInventory(\n        @PathParam(\"productId\") String productId,\n        @QueryParam(\"quantity\") int quantity\n    );\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30b5\u30fc\u30ad\u30c3\u30c8\u30d6\u30ec\u30fc\u30ab\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Path(\"\/resilient\")\npublic class ResilientService {\n    @Inject\n    @RestClient\n    private ExternalService externalService;\n\n    @GET\n    @Path(\"\/data\")\n    @Fallback(fallbackMethod = \"getFallbackData\")\n    @Timeout(500)  \/\/ 500\u30df\u30ea\u79d2\u3067\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\n    @Retry(maxRetries = 3)\n    @CircuitBreaker(\n        requestVolumeThreshold = 4,\n        failureRatio = 0.5,\n        delay = 1000,\n        successThreshold = 2\n    )\n    public Response getData() {\n        return Response.ok(externalService.fetchData()).build();\n    }\n\n    public Response getFallbackData() {\n        \/\/ \u30d5\u30a9\u30fc\u30eb\u30d0\u30c3\u30af\u30ed\u30b8\u30c3\u30af\n        return Response.ok(new FallbackData()).build();\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u5206\u6563\u30c8\u30ec\u30fc\u30b7\u30f3\u30b0\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Provider\npublic class TracingFilter implements ContainerRequestFilter, ContainerResponseFilter {\n    @Inject\n    private Tracer tracer;\n\n    @Override\n    public void filter(ContainerRequestContext requestContext) {\n        Span span = tracer.buildSpan(\"http-request\")\n            .withTag(\"http.method\", requestContext.getMethod())\n            .withTag(\"http.url\", requestContext.getUriInfo().getPath())\n            .start();\n\n        requestContext.setProperty(\"span\", span);\n    }\n\n    @Override\n    public void filter(ContainerRequestContext requestContext,\n                      ContainerResponseContext responseContext) {\n        Span span = (Span) requestContext.getProperty(\"span\");\n        if (span != null) {\n            span.setTag(\"http.status_code\", \n                responseContext.getStatus());\n            span.finish();\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-23\">\u30b3\u30f3\u30c6\u30ca\u5316\u3068\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8\u306e\u8003\u616e\u70b9<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Dockerfile\u306e\u6700\u9069\u5316<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30d3\u30eb\u30c9\u30b9\u30c6\u30fc\u30b8\nFROM maven:3.8.3-openjdk-17 AS build\nWORKDIR \/app\nCOPY pom.xml .\nCOPY src .\/src\nRUN mvn clean package\n\n# \u5b9f\u884c\u30b9\u30c6\u30fc\u30b8\nFROM openjdk:17-slim\nWORKDIR \/app\nCOPY --from=build \/app\/target\/*.jar app.jar\n\n# \u30d8\u30eb\u30b9\u30c1\u30a7\u30c3\u30af\u306e\u8a2d\u5b9a\nHEALTHCHECK --interval=30s --timeout=3s \\\n    CMD curl -f http:\/\/localhost:8080\/health || exit 1\n\nEXPOSE 8080\nENTRYPOINT [\"java\", \"-jar\", \"app.jar\"]<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Kubernetes\u8a2d\u5b9a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: order-service\nspec:\n  replicas: 3\n  selector:\n    matchLabels:\n      app: order-service\n  template:\n    metadata:\n      labels:\n        app: order-service\n    spec:\n      containers:\n      - name: order-service\n        image: order-service:latest\n        ports:\n        - containerPort: 8080\n        readinessProbe:\n          httpGet:\n            path: \/health\n            port: 8080\n          initialDelaySeconds: 20\n          periodSeconds: 10\n        livenessProbe:\n          httpGet:\n            path: \/health\n            port: 8080\n          initialDelaySeconds: 30\n          periodSeconds: 15\n        env:\n        - name: PAYMENT_SERVICE_URL\n          valueFrom:\n            configMapKeyRef:\n              name: service-config\n              key: payment.service.url\n        resources:\n          requests:\n            memory: \"256Mi\"\n            cpu: \"200m\"\n          limits:\n            memory: \"512Mi\"\n            cpu: \"500m\"\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: order-service\nspec:\n  selector:\n    app: order-service\n  ports:\n  - port: 80\n    targetPort: 8080\n  type: LoadBalancer<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u8a2d\u5b9a\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@ApplicationScoped\npublic class ConfigurationProvider {\n    @Inject\n    @ConfigProperty(name = \"payment.service.url\")\n    String paymentServiceUrl;\n\n    @Inject\n    @ConfigProperty(name = \"inventory.service.url\")\n    String inventoryServiceUrl;\n\n    @Inject\n    @ConfigProperty(name = \"circuit.breaker.timeout\", \n                   defaultValue = \"1000\")\n    int circuitBreakerTimeout;\n\n    @Produces\n    @ApplicationScoped\n    public ServiceConfig createServiceConfig() {\n        return ServiceConfig.builder()\n            .paymentServiceUrl(paymentServiceUrl)\n            .inventoryServiceUrl(inventoryServiceUrl)\n            .circuitBreakerTimeout(circuitBreakerTimeout)\n            .build();\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u4f8b\u306f\u3001JAX-RS\u3092\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3067\u6d3b\u7528\u3059\u308b\u969b\u306e\u4e3b\u8981\u306a\u30dd\u30a4\u30f3\u30c8\u3092\u793a\u3057\u3066\u3044\u307e\u3059\u3002\u30b5\u30fc\u30d3\u30b9\u9593\u901a\u4fe1\u3001\u30ec\u30b8\u30ea\u30a8\u30f3\u30b9\u3001\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u3001\u904b\u7528\u6027\u306a\u3069\u306e\u91cd\u8981\u306a\u5074\u9762\u3092\u30ab\u30d0\u30fc\u3057\u3066\u304a\u308a\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306e\u53c2\u8003\u3068\u3057\u3066\u6d3b\u7528\u3067\u304d\u307e\u3059\u3002\u7279\u306b\u3001MicroProfile\u306e\u6a5f\u80fd\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5805\u7262\u306a\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u306e\u69cb\u7bc9\u304c\u53ef\u80fd\u3068\u306a\u308a\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":{"0":"post-1197","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-java","7":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1197","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1197"}],"version-history":[{"count":1,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1197\/revisions"}],"predecessor-version":[{"id":1198,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1197\/revisions\/1198"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}