SoFunction
Updated on 2025-04-05

Solon MVC’s @Mapping usage example

In Solon Mvc, the @Mapping annotation is usually used for request path mapping with @Controller and @Remoting. Moreover, it is only supported on public functions or classes.

1. Annotation attributes

property illustrate Remark
value path Alias ​​with path
path path Alias ​​each other with value
method Request method limitation (def=all) Available@Post@Getetc. Annotation replaces this property
consumes Specify the type of submission to process the request Available@ConsumesAnnotation replaces this property
produces Specify the returned content type Available@ProducesAnnotation replaces this property
multipart Declare support for multi-shard requests (def=false) If false, it will be automatically identified

When method=all, the request method is not limited

2. Supported path mapping expressions

symbol illustrate Example
** Any character, unlimited number of segments **or/user/**
* Any character /user/*
? Disposable /user/?
/ Path fragment start and spacer /or/user
{name} Path variable declaration /user/{name}

Path combination (controller mapping and action mapping) and application examples:

import ;
import ;
@Mapping("/user") //or "user", the beginning will automatically be filled with "/"@Controller
public void DemoController{
    @Mapping("") //=/user
    public void home(){ }
    @Mapping("/") //=/user/, there is a difference from the above, please pay attention.    public void home2(){ }
    @Mapping("/?") //=/user/ or /user is different from the above, please pay attention.    public void home3(){ }
    @Mapping("list") //=/user/list , the interval will automatically be filled with "/"    public void getList(){ }
    @Mapping("/{id}") //=/user/{id}
    public void getOne(long id){ }
    @Mapping("/ajax/**") //=/user/ajax/**
    public void ajax(){ }
}

Reminder: One@MappingFunctions do not support mapping of multiple paths

3. Parameter injection

Injectable objects with non-requested parameters:

type illustrate
Context Request context()
Locale Requested regional information, required during internationalization
ModelAndView Model and view object()

Support automatic conversion injection of request parameters:

  • When the variable name has corresponding request parameters (that is, there is a name that can match the request parameters on it)
    • Will directly try to convert the request parameter value
  • When the variable name has no corresponding request parameter
    • When the variable is an entity: All request parameters will be injected as attributes
    • Otherwise, inject null

Supports direct injection of various forms of request parameters:

  • queryString
  • form-data
  • x-www-form-urlencoded
  • path
  • json body

Among them, queryString, form-data, x-www-form-urlencoded, path parameters support unified acquisition of () interface.

import ;
import ;
import ;
import ;
@Mapping("/user") 
@Controller
public void DemoController{
    //Injectable object for non-requested parameters    @Mapping("case1")
    public void case1(Context ctx, Locale locale , ModelAndView mv){ }
    //Request parameters (can be bulk; support queryString, form; json, or other serialization formats supported)    @Mapping("case2")
    public void case2(String userName, String nickName, long[] ids, List<String> names){ }
    //Request parameters (can be a complete structure; support queryString, form; json, or other serialization formats supported    @Mapping("case3")
    public void case3(UserModel user){ }
    //It can also be a mix    @Mapping("case4")
    public void case4(Context ctx, UserModel user, String userName){  }
    //Upload the file //Note that the name matches the <input type='file' name="file1" />    @Mapping("case5")
    public void case5(UploadedFile file1, UploadedFile file2){ } 
    // Upload multiple files with the same name    @Mapping("case6")
    public void case6(UploadedFile[] file){ }  
}

remind:?user[name]=1&ip[0]=a&ip[1]=b&=1Style parameter injection requires the introduction of plug-ins:solon-serialization-properties

4. Parameter injection with annotations

annotation:

annotation illustrate
@Param Inject request parameters (including: query-string, form). Plays the role of specifying names, default values, etc.
@Header Injection request header
@Cookie Inject request cookie
@Path Inject the request path variable (because the framework will automatically process it, this is just for easy document generation under the identification)
@Body Inject the request body (usually automatically processed. It is only required when the body's String, InputSteam, Map)

Annotation related attributes:

property illustrate Applicable notes
value Parameter name @Param, @Header, @Cookie, @Path
name Parameter name (aliases with value) @Param, @Header, @Cookie, @Path
required Must be @Param, @Header, @Cookie, @Body
defaultValue default value @Param, @Header, @Cookie, @Body
import ;
import ;
import ;
import ;
import ;
@Mapping("/user") 
@Controller
public void DemoController{
    @Mapping("case1")
    public void case1(@Body String bodyStr){   }
    @Mapping("case2")
    public void case2(@Body Map&lt;String,String&gt; paramMap, @Header("Token") String token){ }
    @Mapping("case3")
    public void case3(@Body InputStream stream, @Cookie("Token") token){  }
    //This use case adds @Body and does not add the same effect as    @Mapping("case4")
    public void case4(@Body UserModel user){  } 
    @Mapping("case5/{id}")
    public void case5(String id){  }
    //If the names are different, it is necessary to use @Path // Otherwise it will be automatically processed (as above)    @Mapping("case5_2/{id}")
    public void case5_2(@Path("id") String name){  } 
    @Mapping("case6")
    public void case6(String name){ }
    //If the names are different, it is necessary to use @Param // Otherwise it will be automatically processed (as above)    @Mapping("case6_2")
    public void case6_2(@Param("id") String name){ } 
    //If you want the default value, you need to use @Param    @Mapping("case6_3")
    public void case6_3(@Param(defaultValue="world") String name){ }
    @Mapping("case7")
    public void case7(@Header String token){ }
    @Mapping("case7_2")
    public void case7_2(@Header String[] user){ } //v2.4.0 support}

5. Request method is limited

You can add one or more @Mppay annotations to limit the request method (if you do not limit, all request methods are supported)

Request method limited annotation illustrate
@Get Limited to Http Get request method
@Post Limited to Http Post request method
@Put Limited to Http Put request method
@Delete Limited to Http Delete request method
@Patch Limited to Http Patch request method
@Head Limited to Http Head request method
@Options Limited to Http Options request method
@Trace Limited to Http Trace request method
@Http Limited to all request methods for Http
@Message Limited to Message request method
@To Tag forwarding target
@WebSokcet Limited to WebSokcet request method
@Sokcet Limited to Sokcet request method
@All Allow all request methods (default)
Other limited notes illustrate
@Produces Declare the output content type
@Consumes Declare the input content type (when the output content type does not contain the letter @Consumes, the response is 415 status code)
@Multipart Explicitly declare support for Multipart input

example:

import ;
@Mapping("/user") 
@Controller
public void DemoController{
    @Get
    @Mapping("case1")
    public void case1(Context ctx, Locale locale , ModelAndView mv){ }
    //You can also use the properties of Mapping to limit it directly.  .  .  But it looks good without using annotations    @Mapping(path = "case1_2", method = )
    public void case1_2(Context ctx, Locale locale , ModelAndView mv){ }
    @Put
    @Message
    @Mapping("case2")
    public void case2(String userName, String nickName){ }
    //If there is no output declaration, the side string output defaults to "text/plain"    @Produces(MimeType.APPLICATION_JSON_VALUE)
    @Mapping("case3")
    public String case3(){
        return "{code:1}";
    }
    ////You can also use the properties of Mapping to limit it directly.  .  .  But it looks good without using annotations    @Mapping(path= "case3_2", produces=MimeType.APPLICATION_JSON_VALUE))
    public String case3_2(){
        return "{code:1}";
    }
    //If there is no output declaration, the side object output defaults to "application/json"    @Mapping("case3_3")
    public User case3_3(){
        return new User();
    }
}

6. Output type

@Mapping("/user") 
@Controller
public void DemoController{
    //Output view and model, output the final format after backend rendering    @Maping("case1")
    public ModelAndView case1(){
        ModelAndView mv = new ModelAndView();
        ("name", "world");
        ("");
        return mv;
    }
    //Output structure, the default output will be rendered in josn format and then output    @Maping("case2")
    public UserModel case2(){
        return new UserModel();
    }
    //Output download file    @Maping("case3")
    public Object case3(){
        return new File(...); //or return new DownloadedFile(...);    }
}

7. Parent class inheritance support

@Mapping("user")
public void UserController extends CrudControllerBase<User>{
}
public class CrudControllerBase<T>{
    @Post
    @Mapping("add")
    public void add(T t){
        ...
    }
    @Delete
    @Mapping("remove")
    public void remove(T t){
        ...
    }
}

This is the end of this article about the example usage of @Mapping for Solon MVC. For more related Solon MVC @Mapping, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!