refactoring code in controller

Hi,
I have a following function in spring mvc controller :
@RequestMapping(value = "/snippets/{id}", method = RequestMethod.GET)
    public ModelAndView showSnippet(@PathVariable String id) {
        Snippet snippet = snippetDao.getSnippetById(id);
        String mode = snippet.getMode();
        ObjectMapper objectMapper = new ObjectMapper();
        String extraScripts = "";

        try {
            byte[] jsonData = Files.readAllBytes(Paths.get("utils/meta.json"));
            JsonNode rootNode = objectMapper.readTree(jsonData);
            JsonNode deps = rootNode.path("deps");
            JsonNode modeString = deps.path(mode);
            String jsFileList = modeString.getTextValue();
            String[] jsFileNames = jsFileList.split(",");
            for (int i = 0; i < jsFileNames.length; i++) {
                extraScripts += "<script src=\"/resources/lib/codemirror" + jsFileNames[i] + "\"></script>\n";
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        ModelAndView mav = new ModelAndView("snippet");
        snippet.setText(StringUtils.replaceEach(snippet.getText(), new String[]{"&", "\"", "<", ">"}, new String[]{"&amp;", "&quot;", "&lt;", "&gt;"}));
        mav.addObject("snippet", snippet);
        mav.addObject("extraScripts", extraScripts);
        return mav;
    }

Open in new window


The meta.json file looks like this :
 {
	"extensions" : {
		"text/apl": "apl",
		"application/pgp": "pgp",
		"text/x-ttcn-asn": "asn",
		"text/x-csrc": "c",
		"text/x-c++src": "cpp",
		"text/x-cobol": "cob",
		"text/x-csharp": "cs",
		"text/x-clojure": "clj",
		"text/x-cmake": "cmake",
		"text/x-coffeescript": "coffee",
		"text/x-common-lisp": "cl",
		"application/x-cypher-query": "cyp",
		"text/x-cython": "pyx",
		"text/css": "css",
		"text/x-cassandra": "cql",
		"text/x-d": "d",
		"application/dart": "dart",
		"text/x-diff": "diff",
		"text/x-django": "py",
		"application/xml-dtd": "dtd",
		"text/x-dylan": "dylan",
		"text/x-ecl": "ecl",
		"text/x-eiffel": "e",
		"application/x-ejs": "ejs",
		"application/x-erb": "erb",
		"text/x-erlang": "erl",
		"text/x-forth": "forth",
		"text/x-fortran": "f",
		"text/x-fsharp": "fs",
		"text/x-gas": "s",
		"text/x-feature": "feature",
		"text/x-go": "go",
		"text/x-groovy": "groovy",
		"text/x-haml": "haml",
		"text/x-haskell": "hs",
		"text/x-haxe": "hx",
		"text/x-hxml": "hxml",
		"application/x-aspx": "asp",
		"text/html": "html",
		"message/http": "http",
		"text/x-idl": "pro",
		"text/x-jade": "jade",
		"text/x-java": "java",
		"application/x-jsp": "jsp",
		"text/javascript": "js",
		"application/json": "json",
		"application/ld+json": "jsonld",
		"text/x-julia": "jl",
		"text/x-kotlin": "kt",
		"text/x-less": "less",
		"text/x-livescript": "ls",
		"text/x-lua": "lua",
		"text/x-markdown": "markdown",
		"text/x-mathematica": "m",
		"text/x-modelica": "mo",
		"text/n-triples": "nt",
		"text/x-objectivec": "m",
		"text/x-ocaml": "ml",
		"text/x-octave": "m",
		"text/x-pascal": "p",
		"text/x-perl": "pl",
		"application/x-httpd-php": "php",
		"text/x-pig": "pig",
		"text/plain": "txt",
		"text/x-plsql": "pls",
		"text/x-properties": "properties",
		"text/x-python": "py",
		"text/x-puppet": "pp",
		"text/x-q": "q",
		"text/x-rsrc": "r",
		"text/x-rst": "rst",
		"text/x-rpm-spec": "spec",
		"text/x-ruby": "rb",
		"text/x-rustsrc": "rs",
		"text/x-sass": "sass",
		"text/x-scala": "scala",
		"text/x-scheme": "scm",
		"text/x-scss": "scss",
		"text/x-sh": "sh",
		"application/sieve": "siv",
		"text/x-slim": "slim",
		"text/x-stsrc": "st",
		"text/x-smarty": "tpl",
		"text/x-soy": "soy",
		"application/sparql-query": "rq",
		"text/x-sql": "sql",
		"text/x-latex": "text",
		"text/x-systemverilog": "v",
		"text/x-tcl": "tcl",
		"text/x-textile": "textile",
		"text/x-toml": "toml",
		"troff": "1",
		"text/x-ttcn": "ttcn",
		"text/x-ttcn-cfg": "cfg",
		"text/turtle": "ttl",
		"application/typescript": "ts",
		"text/x-vb": "vb",
		"text/vbscript": "vbs",
		"text/velocity": "vtl",
		"text/x-verilog": "v",
		"application/xml": "xml",
		"application/xquery": "xquery",
		"text/x-yaml": "yaml",
		"text/x-z80": "z80"
	} ,

	"deps" : {
		"text/apl": "/mode/apl/apl.js",
		"application/pgp": "/mode/asciiarmor/asciiarmor.js",
		"text/x-ttcn-asn": "/mode/asn.1/asn.1.js",
		"text/x-asterisk": "/mode/asterisk/asterisk.js",
		"text/x-csrc": "/mode/clike/clike.js",
		"text/x-c++src": "/mode/clike/clike.js",
		"text/x-cobol": "/mode/cobol/cobol.js",
		"text/x-csharp": "/mode/clike/clike.js",
		"text/x-clojure": "/mode/clojure/clojure.js",
		"text/x-cmake": "/mode/cmake/cmake.js",
		"text/x-coffeescript": "/mode/coffeescript/coffeescript.js",
		"text/x-common-lisp": "/mode/commonlisp/commonlisp.js",
		"application/x-cypher-query": "/mode/cypher/cypher.js",
		"text/x-cython": "/mode/python/python.js",
		"text/css": "/mode/css/css.js",
		"text/x-cassandra": "/mode/sql/sql.js",
		"text/x-d": "/mode/d/d.js",
		"application/dart": "/mode/clike/clike.js,/mode/dart/dart.js",
		"text/x-diff": "/mode/diff/diff.js",
		"text/x-django": "/mode/xml/xml.js,/mode/javascript/javascript.js,/mode/css/css.js,/mode/htmlmixed/htmlmixed.js,/addon/mode/overlay.js,/mode/django/django.js",
		"text/x-dockerfile": "/addon/mode/simple.js,/mode/dockerfile/dockerfile.js",
		"application/xml-dtd": "/mode/dtd/dtd.js",
		"text/x-dylan": "/mode/dylan/dylan.js",
		"text/x-ebnf": "/mode/ebnf/ebnf.js",
		"text/x-ecl": "/mode/ecl/ecl.js",
		"text/x-eiffel": "/mode/eiffel/eiffel.js",
		"application/x-ejs": "/mode/htmlembedded/htmlembedded.js",
		"application/x-erb": "/mode/htmlembedded/htmlembedded.js",
		"text/x-erlang": "/mode/erlang/erlang.js",
		"text/x-forth": "/mode/forth/forth.js",
		"text/x-fortran": "/mode/fortran/fortran.js",
		"text/x-fsharp": "/mode/mllike/mllike.js",
		"text/x-gas": "/mode/gas/gas.js",
		"text/x-feature": "/mode/gherkin/gherkin.js",
		"text/x-gfm": "/mode/xml/xml.js,/mode/meta.js,/mode/markdown/markdown.js,/addon/mode/overlay.js,/mode/gfm/gfm.js",
		"text/x-go": "/mode/go/go.js",
		"text/x-groovy": "/mode/groovy/groovy.js",
		"text/x-haml": "/mode/xml/xml.js,/mode/javascript/javascript.js,/mode/css/css.js,/mode/htmlmixed/htmlmixed.js,/mode/ruby/ruby.js,/mode/haml/haml.js",
		"text/x-haskell": "/mode/haskell/haskell.js",
		"text/x-haxe": "/mode/haxe/haxe.js",
		"text/x-hxml": "/mode/haxe/haxe.js",
		"application/x-aspx": "/mode/htmlembedded/htmlembedded.js",
		"text/html": "/mode/xml/xml.js,/mode/javascript/javascript.js,/mode/css/css.js,/mode/htmlmixed/htmlmixed.js",
		"message/http": "/mode/http/http.js",
		"text/x-idl": "/mode/idl/idl.js",
		"text/x-jade": "/mode/xml/xml.js,/mode/javascript/javascript.js,/mode/css/css.js,/mode/htmlmixed/htmlmixed.js,/mode/jade/jade.js",
		"text/x-java": "/mode/clike/clike.js",
		"application/x-jsp": "/mode/htmlembedded/htmlembedded.js",
		"text/javascript": "/mode/javascript/javascript.js",
		"application/json": "/mode/javascript/javascript.js",
		"application/ld+json": "/mode/javascript/javascript.js",
		"text/x-julia": "/mode/julia/julia.js",
		"text/x-kotlin": "/mode/kotlin/kotlin.js",
		"text/x-less": "/mode/css/css.js",
		"text/x-livescript": "/mode/livescript/livescript.js",
		"text/x-lua": "/mode/lua/lua.js",
		"text/x-markdown": "/mode/xml/xml.js,/mode/meta.js,/mode/markdown/markdown.js",
		"text/mirc": "/mode/mirc/mirc.js",
		"text/x-mariadb": "/mode/sql/sql.js",
		"text/x-mathematica": "/mode/mathematica/mathematica.js",
		"text/x-modelica": "/mode/modelica/modelica.js",
		"text/x-mumps": "/mode/mumps/mumps.js",
		"text/x-mssql": "/mode/sql/sql.js",
		"text/x-mysql": "/mode/sql/sql.js",
		"text/x-nginx-conf": "/mode/nginx/nginx.js",
		"text/n-triples": "/mode/ntriples/ntriples.js",
		"text/x-objectivec": "/mode/clike/clike.js",
		"text/x-ocaml": "/mode/mllike/mllike.js",
		"text/x-octave": "/mode/octave/octave.js",
		"text/x-pascal": "/mode/pascal/pascal.js",
		"null": "/mode/pegjs/pegjs.js",
		"text/x-perl": "/mode/perl/perl.js",
		"application/x-httpd-php": "/mode/xml/xml.js,/mode/javascript/javascript.js,/mode/css/css.js,/mode/htmlmixed/htmlmixed.js,/mode/clike/clike.js,/mode/php/php.js",
		"text/x-pig": "/mode/pig/pig.js",
		"text/plain": "/mode/null/null.js",
		"text/x-plsql": "/mode/sql/sql.js",
		"text/x-properties": "/mode/properties/properties.js",
		"text/x-python": "/mode/python/python.js",
		"text/x-puppet": "/mode/puppet/puppet.js",
		"text/x-q": "/mode/q/q.js",
		"text/x-rsrc": "/mode/r/r.js",
		"text/x-rst": "/mode/python/python.js,/mode/stex/stex.js,/addon/mode/overlay.js,/mode/rst/rst.js",
		"text/x-rpm-changes": "/mode/rpm/rpm.js",
		"text/x-rpm-spec": "/mode/rpm/rpm.js",
		"text/x-ruby": "/mode/ruby/ruby.js",
		"text/x-rustsrc": "/mode/rust/rust.js",
		"text/x-sass": "/mode/sass/sass.js",
		"text/x-scala": "/mode/clike/clike.js",
		"text/x-scheme": "/mode/scheme/scheme.js",
		"text/x-scss": "/mode/css/css.js",
		"text/x-sh": "/mode/shell/shell.js",
		"application/sieve": "/mode/sieve/sieve.js",
		"text/x-slim": "/mode/xml/xml.js,/mode/javascript/javascript.js,/mode/css/css.js,/mode/htmlmixed/htmlmixed.js,/mode/ruby/ruby.js,/mode/slim/slim.js",
		"text/x-stsrc": "/mode/smalltalk/smalltalk.js",
		"text/x-smarty": "/mode/smarty/smarty.js",
		"text/x-solr": "/mode/solr/solr.js",
		"text/x-soy": "/mode/soy/soy.js",
		"application/sparql-query": "/mode/sparql/sparql.js",
		"text/x-spreadsheet": "/mode/spreadsheet/spreadsheet.js",
		"text/x-sql": "/mode/sql/sql.js",
		"text/x-stex": "/mode/stex/stex.js",
		"text/x-latex": "/mode/stex/stex.js",
		"text/x-systemverilog": "/mode/verilog/verilog.js",
		"text/x-tcl": "/mode/tcl/tcl.js",
		"text/x-textile": "/mode/textile/textile.js",
		"text/x-tiddlywiki": "/mode/tiddlywiki/tiddlywiki.js",
		"text/tiki": "/mode/tiki/tiki.js",
		"text/x-toml": "/mode/toml/toml.js",
		"text/x-tornado": "/mode/tornado/tornado.js",
		"troff": "/mode/troff/troff.js",
		"text/x-ttcn": "/mode/ttcn/ttcn.js",
		"text/x-ttcn-cfg": "/mode/ttcn-cfg/ttcn-cfg.js",
		"text/turtle": "/mode/turtle/turtle.js",
		"application/typescript": "/mode/javascript/javascript.js",
		"text/x-twig": "/mode/twig/twig.js",
		"text/x-vb": "/mode/vb/vb.js",
		"text/vbscript": "/mode/vbscript/vbscript.js",
		"text/velocity": "/mode/velocity/velocity.js",
		"text/x-verilog": "/mode/verilog/verilog.js",
		"application/xml": "/mode/xml/xml.js",
		"application/xquery": "/mode/xquery/xquery.js",
		"text/x-yaml": "/mode/yaml/yaml.js",
		"text/x-z80": "/mode/z80/z80.js"
	}
}

Open in new window


The code basically gets the mode and parses the json to get the corresponsing filenames and returns them in an object.
I want to improve this code , the questions i am having is :
1) should this code be in controller ?
2) each time the request hits snippets/{id} i am parsing the whole json each time. Is there some way i can optimize this ?

Thanks
Rohit BajajAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mccarlIT Business Systems Analyst / Software DeveloperCommented:
2) Yes, you should NOT parse the JSON for every request received.

1) No, it shouldn't be in the controller.

My suggestion to cater both answers to your questions, is to make a separate class, say MetaData, that represents this mapping that you have. Essentially the data that you are using represents a simple interface, as you said "gets the mode ... to get the corresponsing filenames", so the class should have a simple method of something like this...     List<String> getDeps(String mode)

Then in the constructor of your MetaData object is where you load the meta.json file and parse the JSON data. You would then store the parsed data in a data structure such as.... Map<String, List<String>> that is a private field of this MetaData class. And then the getDeps method above can simple get the appropriate entry in the Map object and return the resultant list of Strings (ie. filenames).

Then you controller just holds a reference to a MetaData object, that it can call the getDeps method on at any time and it gets returned the caches list of filenames from MetaData internal Map.

If you only use this information in the one controller, you could simply initialize the controller instance of MetaData with.... = new MetaData();      Otherwise, you could make it a Spring bean in the XML and then inject it into the controller (and anywhere else it might be needed)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Rohit BajajAuthor Commented:
HI mccarl,
Thanks for help.
one more thing i want to ask. Where should i place my MetaData.java file ?
My current project structure is :
src
main (under main i have db, java, resources,webapp directories)
under java i have the following directories ( controller, model, exception,dao)


And directly under the project i have made a folder utils inside which i have placed meta.json file.

Is it okay to declare the MetaData.java as @Component because in that way i wouldnt need to declare it as a bean in an xml and directly use it in my controller?

Thanks
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
under java i have the following directories ( controller, model, exception,dao)
I would probably call this a "service" so I would create another directory under java called "service" (ie. along side the other 4 directories). If you don't want an extra directory, then the next most appropriate place would probably be "dao" as this class will be an Object that Accesses Data in the meta.json file.

Is it okay to declare the MetaData.java as @Component

Yes, that would be appropriate if you are already injecting other objects in that way. However, I would use one of the more specific specializations of @Component just to be more descriptive. If you go with what I mention above and put your class in a "service" package, then use the @Service annotation, or if you put it in your existing "dao" package, use the @Repository annotation that you other dao's would be using.

Either annotation, @Service or @Repository, is also a @Component and so the object will work as you expect it to, ie. you don't need to explicitly declare it in your XML.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.